├── .gitignore ├── .vscode ├── c_cpp_properties.json └── settings.json ├── CMakeLists.txt ├── README.md ├── build.sh ├── config.ini ├── enuplayerone ├── README.md ├── enu.token │ ├── enu.token.abi │ ├── enu.token.cpp │ ├── enu.token.hpp │ └── enu.token.wasm ├── enu_init.sh ├── playerone.abi ├── playerone.cpp ├── playerone.sh ├── playerone.wasm └── playerone_init.sh ├── eos_init.sh ├── eosio.token ├── CMakeLists.txt ├── abi │ └── eosio.token.abi └── eosio.token.cpp ├── img ├── logo.jpg ├── logo1.jpg ├── logo2.jpg └── price.png ├── info.md ├── package-lock.json ├── package.json ├── playerone.sh ├── playerone ├── CMakeLists.txt ├── README.md ├── abi │ └── playerone.abi ├── include │ └── eosio.token │ │ ├── eosio.token.cpp │ │ └── eosio.token.hpp └── playerone.cpp ├── playerone_buy.sh ├── playerone_init.sh ├── playerone_main_init.sh ├── playerone_presale.sh ├── playerone_sell.sh ├── playerone_stake.sh ├── run.sh ├── scripts.txt └── utils.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.key 2 | 3 | *.secure.sh 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 28 | .grunt 29 | 30 | # Bower dependency directory (https://bower.io/) 31 | bower_components 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (https://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules/ 41 | jspm_packages/ 42 | 43 | # TypeScript v1 declaration files 44 | typings/ 45 | 46 | # Optional npm cache directory 47 | .npm 48 | 49 | # Optional eslint cache 50 | .eslintcache 51 | 52 | # Optional REPL history 53 | .node_repl_history 54 | 55 | # Output of 'npm pack' 56 | *.tgz 57 | 58 | # Yarn Integrity file 59 | .yarn-integrity 60 | 61 | # dotenv environment variables file 62 | .env 63 | 64 | # next.js build output 65 | .next 66 | 67 | # VS code 68 | .vscode/ 69 | 70 | # cmake 71 | build/ 72 | CMakeFiles/ 73 | CMakeCache.txt 74 | 75 | # eos 76 | include/ 77 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "/usr/local/eosio.wasmsdk/include/**" 8 | ], 9 | "defines": [], 10 | "macFrameworkPath": [ 11 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks" 12 | ], 13 | "compilerPath": "/usr/bin/clang", 14 | "cStandard": "c11", 15 | "cppStandard": "c++17", 16 | "intelliSenseMode": "clang-x64" 17 | } 18 | ], 19 | "version": 4 20 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.ignoreLimitWarning": true, 3 | "files.associations": { 4 | "__functional_03": "cpp", 5 | "__tree": "cpp", 6 | "functional": "cpp", 7 | "memory": "cpp", 8 | "exception": "cpp", 9 | "__hash_table": "cpp", 10 | "__split_buffer": "cpp", 11 | "string": "cpp", 12 | "unordered_map": "cpp", 13 | "unordered_set": "cpp", 14 | "vector": "cpp", 15 | "__locale": "cpp", 16 | "ios": "cpp", 17 | "hashtable": "cpp", 18 | "__bit_reference": "cpp", 19 | "__string": "cpp", 20 | "algorithm": "cpp", 21 | "string_view": "cpp", 22 | "hash_map": "cpp", 23 | "map": "cpp", 24 | "set": "cpp", 25 | "typeindex": "cpp", 26 | "typeinfo": "cpp", 27 | "tuple": "cpp", 28 | "iterator": "cpp", 29 | "deque": "cpp", 30 | "optional": "cpp", 31 | "list": "cpp", 32 | "queue": "cpp", 33 | "stack": "cpp", 34 | "utility": "cpp", 35 | "chrono": "cpp", 36 | "__functional_base": "cpp", 37 | "atomic": "cpp", 38 | "bitset": "cpp", 39 | "limits": "cpp", 40 | "locale": "cpp", 41 | "ratio": "cpp", 42 | "system_error": "cpp", 43 | "type_traits": "cpp", 44 | "future": "cpp", 45 | "array": "cpp", 46 | "variant": "cpp", 47 | "iosfwd": "cpp", 48 | "initializer_list": "cpp", 49 | "*.ipp": "cpp", 50 | "stdexcept": "cpp" 51 | }, 52 | "code-runner.executorMap": { 53 | "javascript": "node", 54 | "java": "cd $dir && javac $fileName && java $fileNameWithoutExt", 55 | "c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", 56 | "cpp": "cd $dir && cd .. && bash ./build.sh", 57 | "objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt", 58 | "php": "php", 59 | "python": "python -u", 60 | "perl": "perl", 61 | "perl6": "perl6", 62 | "ruby": "ruby", 63 | "go": "go run", 64 | "lua": "lua", 65 | "groovy": "groovy", 66 | "powershell": "powershell -ExecutionPolicy ByPass -File", 67 | "bat": "cmd /c", 68 | "shellscript": "bash", 69 | "fsharp": "fsi", 70 | "csharp": "scriptcs", 71 | "vbscript": "cscript //Nologo", 72 | "typescript": "ts-node", 73 | "coffeescript": "coffee", 74 | "scala": "scala", 75 | "swift": "swift", 76 | "julia": "julia", 77 | "crystal": "crystal", 78 | "ocaml": "ocaml", 79 | "r": "Rscript", 80 | "applescript": "osascript", 81 | "clojure": "lein exec", 82 | "haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt", 83 | "rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt", 84 | "racket": "racket", 85 | "ahk": "autohotkey", 86 | "autoit": "autoit3", 87 | "dart": "dart", 88 | "pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt", 89 | "d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt", 90 | "haskell": "runhaskell", 91 | "nim": "nim compile --verbosity:0 --hints:off --run" 92 | } 93 | } -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TARGET "playerone") 2 | 3 | cmake_minimum_required(VERSION 3.5) 4 | project(eosio_contracts VERSION 1.2.0) 5 | 6 | set(EOSIO_DEPENDENCY "1.1") 7 | set(EOSIO_WASMSDK_DEPENDENCY "1.1") 8 | 9 | if(CMAKE_BUILD_TYPE STREQUAL "Debug") 10 | set(TEST_BUILD_TYPE "Debug") 11 | set(CMAKE_BUILD_TYPE "Release") 12 | else() 13 | set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) 14 | endif() 15 | 16 | if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) 17 | set(EOSIO_ROOT "/usr/local/eosio") 18 | endif() 19 | 20 | if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) 21 | set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") 22 | endif() 23 | 24 | list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) 25 | include(EosioWasmToolchain) 26 | 27 | ### Check the version of wasmsdk 28 | string(FIND "${EOSIO_WASMSDK_VERSION}" "${EOSIO_WASMSDK_DEPENDENCY}" output) 29 | 30 | if (NOT "${output}" EQUAL 0) 31 | message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") 32 | endif() 33 | 34 | include_directories(AFTER ${BOOST_ROOT}/include) 35 | add_subdirectory(${TARGET}) 36 | add_subdirectory(eosio.token) 37 | 38 | if (APPLE) 39 | set(OPENSSL_ROOT "/usr/local/opt/openssl") 40 | elseif (UNIX) 41 | set(OPENSSL_ROOT "/usr/include/openssl") 42 | endif() 43 | set(SECP256K1_ROOT "/usr/local") 44 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Player One Documentaion 2 | 3 | ### Pre-installation 4 | 5 | > Assume you have pre-installed eos https://github.com/EOSIO/eos 6 | 7 | > Assume you have pre-installed eosio.wasmsdk https://github.com/EOSIO/eosio.wasmsdk 8 | 9 | > Assume you have pre-installed eosio.contracts https://github.com/EOSIO/eosio.contracts 10 | 11 | ### Configuration 12 | 13 | #### Copy the eos configure file `config.ini` to the eos config folder 14 | 15 | `nodeos` uses a custom configuration folder. The location of this folder is determined by your system. 16 | 17 | > Mac OS: ~/Library/Application\ Support/eosio/nodeos/config/ 18 | 19 | > Linux: ~/.local/share/eosio/nodeos/config/ 20 | 21 | For example, on Mac: 22 | 23 | ```bash 24 | cp ./config.ini ~/Library/Application\ Support/eosio/nodeos/config/ 25 | ``` 26 | 27 | Then maybe you need change this two dir path in `eos_init.sh` 28 | ```bash 29 | EOS_HOME=../eos 30 | EOS_CONTRACT_HOME=../eosio.contracts 31 | ``` 32 | 33 | #### You need to import the eosio master key to get root privilege in eos 34 | 35 | Before run it you may need to unlock eos wallet. 36 | 37 | ```bash 38 | cleos wallet unlock 39 | ``` 40 | You can find the config infomation in eos config file: `config.ini`. 41 | 42 | ```config 43 | signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 44 | ``` 45 | 46 | Just import the key: 47 | ```bash 48 | cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 49 | ``` 50 | 51 | #### Run local test net and test 52 | 53 | ##### First run the eos local test net 54 | 55 | Run `nodeos` in your `eos build folder`: 56 | 57 | ```bash 58 | ./programs/nodeos/nodeos 59 | ``` 60 | If you need to clear the blockchain data, just remove the eos block data folder. 61 | 62 | For example, on Mac: 63 | ```bash 64 | rm -rf ~/Library/Application\ Support/eosio/nodeos/data/* 65 | ``` 66 | 67 | ##### Then run the all in one script 68 | 69 | Before run it you may need to unlock eos wallet. 70 | 71 | ```bash 72 | cleos wallet unlock 73 | ``` 74 | 75 | Then run. Enjoy! 76 | 77 | ```bash 78 | ./run.sh 79 | ``` 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | if [ -d "build/playerone" ]; then 4 | rm -rf build/playerone; 5 | fi 6 | 7 | printf "\t=========== Building contracts ===========\n\n" 8 | 9 | RED='\033[0;31m' 10 | NC='\033[0m' 11 | 12 | CORES=`getconf _NPROCESSORS_ONLN` 13 | mkdir -p build 14 | pushd build &> /dev/null 15 | cmake ../ 16 | make -j${CORES} 17 | popd &> /dev/null 18 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | # File to read Genesis State from 2 | # genesis-json = 3 | genesis-json = "/opt/eos/bin/data-dir/genesis.json" 4 | 5 | # the endpoint upon which to listen for incoming connections (eosio::bnet_plugin) 6 | bnet-endpoint = 0.0.0.0:4321 7 | 8 | # this peer will request only irreversible blocks from other nodes (eosio::bnet_plugin) 9 | bnet-follow-irreversible = 0 10 | 11 | # the number of threads to use to process network messages (eosio::bnet_plugin) 12 | # bnet-threads = 13 | 14 | # remote endpoint of other node to connect to; Use multiple bnet-connect options as needed to compose a network (eosio::bnet_plugin) 15 | # bnet-connect = 16 | 17 | # this peer will request no pending transactions from other nodes (eosio::bnet_plugin) 18 | bnet-no-trx = false 19 | 20 | # The string used to format peers when logging messages about them. Variables are escaped with ${}. 21 | # Available Variables: 22 | # _name self-reported name 23 | # 24 | # _id self-reported ID (Public Key) 25 | # 26 | # _ip remote IP address of peer 27 | # 28 | # _port remote port number of peer 29 | # 30 | # _lip local IP address connected to peer 31 | # 32 | # _lport local port number connected to peer 33 | # 34 | # (eosio::bnet_plugin) 35 | bnet-peer-log-format = ["${_name}" ${_ip}:${_port}] 36 | 37 | # the location of the blocks directory (absolute path or relative to application data dir) (eosio::chain_plugin) 38 | blocks-dir = "blocks" 39 | 40 | # Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints. (eosio::chain_plugin) 41 | # checkpoint = 42 | 43 | # Override default WASM runtime (eosio::chain_plugin) 44 | # wasm-runtime = 45 | 46 | # Override default maximum ABI serialization time allowed in ms (eosio::chain_plugin) 47 | abi-serializer-max-time-ms = 15000 48 | 49 | # Maximum size (in MiB) of the chain state database (eosio::chain_plugin) 50 | chain-state-db-size-mb = 1024 51 | 52 | # Safely shut down node when free space remaining in the chain state database drops below this size (in MiB). (eosio::chain_plugin) 53 | chain-state-db-guard-size-mb = 128 54 | 55 | # Maximum size (in MiB) of the reversible blocks database (eosio::chain_plugin) 56 | reversible-blocks-db-size-mb = 340 57 | 58 | # Safely shut down node when free space remaining in the reverseible blocks database drops below this size (in MiB). (eosio::chain_plugin) 59 | reversible-blocks-db-guard-size-mb = 2 60 | 61 | # print contract's output to console (eosio::chain_plugin) 62 | contracts-console = false 63 | 64 | # Account added to actor whitelist (may specify multiple times) (eosio::chain_plugin) 65 | # actor-whitelist = 66 | 67 | # Account added to actor blacklist (may specify multiple times) (eosio::chain_plugin) 68 | # actor-blacklist = 69 | 70 | # Contract account added to contract whitelist (may specify multiple times) (eosio::chain_plugin) 71 | # contract-whitelist = 72 | 73 | # Contract account added to contract blacklist (may specify multiple times) (eosio::chain_plugin) 74 | # contract-blacklist = 75 | 76 | # Action (in the form code::action) added to action blacklist (may specify multiple times) (eosio::chain_plugin) 77 | # action-blacklist = 78 | 79 | # Public key added to blacklist of keys that should not be included in authorities (may specify multiple times) (eosio::chain_plugin) 80 | # key-blacklist = 81 | 82 | # Database read mode ("speculative" or "head"). 83 | # In "speculative" mode database contains changes done up to the head block plus changes made by transactions not yet included to the blockchain. 84 | # In "head" mode database contains changes done up to the current head block. 85 | # (eosio::chain_plugin) 86 | read-mode = speculative 87 | 88 | # Track actions which match receiver:action:actor. Actor may be blank to include all. Receiver and Action may not be blank. (eosio::history_plugin) 89 | # filter-on = 90 | 91 | # PEM encoded trusted root certificate (or path to file containing one) used to validate any TLS connections made. (may specify multiple times) 92 | # (eosio::http_client_plugin) 93 | # https-client-root-cert = 94 | 95 | # true: validate that the peer certificates are valid and trusted, false: ignore cert errors (eosio::http_client_plugin) 96 | https-client-validate-peers = 1 97 | 98 | # The local IP and port to listen for incoming http connections; set blank to disable. (eosio::http_plugin) 99 | http-server-address = 127.0.0.1:8888 100 | 101 | # The local IP and port to listen for incoming https connections; leave blank to disable. (eosio::http_plugin) 102 | # https-server-address = 103 | 104 | # Filename with the certificate chain to present on https connections. PEM format. Required for https. (eosio::http_plugin) 105 | # https-certificate-chain-file = 106 | 107 | # Filename with https private key in PEM format. Required for https (eosio::http_plugin) 108 | # https-private-key-file = 109 | 110 | # Specify the Access-Control-Allow-Origin to be returned on each request. (eosio::http_plugin) 111 | access-control-allow-origin = * 112 | 113 | # Specify the Access-Control-Allow-Headers to be returned on each request. (eosio::http_plugin) 114 | # access-control-allow-headers = 115 | 116 | # Specify the Access-Control-Max-Age to be returned on each request. (eosio::http_plugin) 117 | # access-control-max-age = 118 | 119 | # Specify if Access-Control-Allow-Credentials: true should be returned on each request. (eosio::http_plugin) 120 | access-control-allow-credentials = false 121 | 122 | # The maximum body size in bytes allowed for incoming RPC requests (eosio::http_plugin) 123 | max-body-size = 1048576 124 | 125 | # Append the error log to HTTP responses (eosio::http_plugin) 126 | verbose-http-errors = false 127 | 128 | # If set to false, then any incoming "Host" header is considered valid (eosio::http_plugin) 129 | http-validate-host = 1 130 | 131 | # Additionaly acceptable values for the "Host" header of incoming HTTP requests, can be specified multiple times. Includes http/s_server_address by default. (eosio::http_plugin) 132 | # http-alias = 133 | 134 | # The maximum number of pending login requests (eosio::login_plugin) 135 | max-login-requests = 1000000 136 | 137 | # The maximum timeout for pending login requests (in seconds) (eosio::login_plugin) 138 | max-login-timeout = 60 139 | 140 | # The target queue size between nodeos and MongoDB plugin thread. (eosio::mongo_db_plugin) 141 | mongodb-queue-size = 256 142 | 143 | # Required with --replay-blockchain, --hard-replay-blockchain, or --delete-all-blocks to wipe mongo db.This option required to prevent accidental wipe of mongo db. (eosio::mongo_db_plugin) 144 | mongodb-wipe = false 145 | 146 | # If specified then only abi data pushed to mongodb until specified block is reached. (eosio::mongo_db_plugin) 147 | mongodb-block-start = 0 148 | 149 | # MongoDB URI connection string, see: https://docs.mongodb.com/master/reference/connection-string/. If not specified then plugin is disabled. Default database 'EOS' is used if not specified in URI. Example: mongodb://127.0.0.1:27017/EOS (eosio::mongo_db_plugin) 150 | # mongodb-uri = 151 | 152 | # The actual host:port used to listen for incoming p2p connections. (eosio::net_plugin) 153 | p2p-listen-endpoint = 0.0.0.0:9876 154 | 155 | # An externally accessible host:port for identifying this node. Defaults to p2p-listen-endpoint. (eosio::net_plugin) 156 | # p2p-server-address = 157 | 158 | # The public endpoint of a peer node to connect to. Use multiple p2p-peer-address options as needed to compose a network. (eosio::net_plugin) 159 | # p2p-peer-address = 160 | 161 | # Maximum number of client nodes from any single IP address (eosio::net_plugin) 162 | p2p-max-nodes-per-host = 1 163 | 164 | # The name supplied to identify this node amongst the peers. (eosio::net_plugin) 165 | agent-name = "EOS Test Agent" 166 | 167 | # Can be 'any' or 'producers' or 'specified' or 'none'. If 'specified', peer-key must be specified at least once. If only 'producers', peer-key is not required. 'producers' and 'specified' may be combined. (eosio::net_plugin) 168 | allowed-connection = any 169 | 170 | # Optional public key of peer allowed to connect. May be used multiple times. (eosio::net_plugin) 171 | # peer-key = 172 | 173 | # Tuple of [PublicKey, WIF private key] (may specify multiple times) (eosio::net_plugin) 174 | # peer-private-key = 175 | 176 | # Maximum number of clients from which connections are accepted, use 0 for no limit (eosio::net_plugin) 177 | max-clients = 25 178 | 179 | # number of seconds to wait before cleaning up dead connections (eosio::net_plugin) 180 | connection-cleanup-period = 30 181 | 182 | # True to require exact match of peer network version. (eosio::net_plugin) 183 | network-version-match = 0 184 | 185 | # number of blocks to retrieve in a chunk from any individual peer during synchronization (eosio::net_plugin) 186 | sync-fetch-span = 100 187 | 188 | # maximum sizes of transaction or block messages that are sent without first sending a notice (eosio::net_plugin) 189 | max-implicit-request = 1500 190 | 191 | # Enable expirimental socket read watermark optimization (eosio::net_plugin) 192 | use-socket-read-watermark = 0 193 | 194 | # The string used to format peers when logging messages about them. Variables are escaped with ${}. 195 | # Available Variables: 196 | # _name self-reported name 197 | # 198 | # _id self-reported ID (64 hex characters) 199 | # 200 | # _sid first 8 characters of _peer.id 201 | # 202 | # _ip remote IP address of peer 203 | # 204 | # _port remote port number of peer 205 | # 206 | # _lip local IP address connected to peer 207 | # 208 | # _lport local port number connected to peer 209 | # 210 | # (eosio::net_plugin) 211 | # peer-log-format = ["${_name}" ${_ip}:${_port}] 212 | 213 | # Enable block production, even if the chain is stale. (eosio::producer_plugin) 214 | # enable-stale-production = false 215 | 216 | # Start this node in a state where production is paused (eosio::producer_plugin) 217 | pause-on-startup = false 218 | 219 | # Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid (eosio::producer_plugin) 220 | max-transaction-time = 30 221 | 222 | # Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited) (eosio::producer_plugin) 223 | max-irreversible-block-age = -1 224 | 225 | # ID of producer controlled by this node (e.g. inita; may specify multiple times) (eosio::producer_plugin) 226 | # producer-name = 227 | 228 | # (DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times) (eosio::producer_plugin) 229 | # private-key = 230 | 231 | # Key=Value pairs in the form = 232 | # Where: 233 | # is a string form of a vaild EOSIO public key 234 | # 235 | # is a string in the form : 236 | # 237 | # is KEY, or KEOSD 238 | # 239 | # KEY: is a string form of a valid EOSIO private key which maps to the provided public key 240 | # 241 | # KEOSD: is the URL where keosd is available and the approptiate wallet(s) are unlocked (eosio::producer_plugin) 242 | signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 243 | 244 | # Limits the maximum time (in milliseconds) that is allowd for sending blocks to a keosd provider for signing (eosio::producer_plugin) 245 | keosd-provider-timeout = 5 246 | 247 | # account that can not access to extended CPU/NET virtual resources (eosio::producer_plugin) 248 | # greylist-account = 249 | 250 | # offset of non last block producing time in micro second. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later (eosio::producer_plugin) 251 | produce-time-offset-us = 0 252 | 253 | # offset of last block producing time in micro second. Negative number results in blocks to go out sooner, and positive number results in blocks to go out later (eosio::producer_plugin) 254 | last-block-time-offset-us = 0 255 | 256 | # ratio between incoming transations and deferred transactions when both are exhausted (eosio::producer_plugin) 257 | incoming-defer-ratio = 1 258 | 259 | # Lag in number of blocks from the head block when selecting the reference block for transactions (-1 means Last Irreversible Block) (eosio::txn_test_gen_plugin) 260 | txn-reference-block-lag = 0 261 | 262 | # The path of the wallet files (absolute path or relative to application data dir) (eosio::wallet_plugin) 263 | wallet-dir = "." 264 | 265 | # Timeout for unlocked wallet in seconds (default 900 (15 minutes)). Wallets will automatically lock after specified number of seconds of inactivity. Activity is defined as any wallet command e.g. list-wallets. (eosio::wallet_plugin) 266 | unlock-timeout = 900 267 | 268 | # Override default URL of http://localhost:12345 for connecting to yubihsm-connector (eosio::wallet_plugin) 269 | # yubihsm-url = 270 | 271 | # Enables YubiHSM support using given Authkey (eosio::wallet_plugin) 272 | # yubihsm-authkey = 273 | 274 | # Plugin(s) to enable, may be specified multiple times 275 | # plugin = 276 | 277 | # Enable production on a stale chain, since a single-node test chain is pretty much always stale 278 | enable-stale-production = true 279 | # Enable block production with the testnet producers 280 | producer-name = eosio 281 | # Load the block producer plugin, so you can produce blocks 282 | plugin = eosio::producer_plugin 283 | # As well as API and HTTP plugins 284 | plugin = eosio::chain_api_plugin 285 | plugin = eosio::http_plugin 286 | # This will be used by the validation step below, to view history 287 | plugin = eosio::history_api_plugin 288 | -------------------------------------------------------------------------------- /enuplayerone/README.md: -------------------------------------------------------------------------------- 1 | ### CLAUSE NAME: Warranty 2 | WARRANTY. The invoker of the contract action shall uphold its Obligations under this Contract in a timely and workmanlike manner, using knowledge and recommendations for performing the services which meet generally acceptable standards set forth by EOS.IO Blockchain Block Producers. 3 | 4 | ### CLAUSE NAME: Default 5 | DEFAULT. The occurrence of any of the following shall constitute a material default under this Contract: 6 | 7 | ### CLAUSE NAME: Remedies 8 | REMEDIES. In addition to any and all other rights a party may have available according to law, if a party defaults by failing to substantially perform any provision, term or condition of this Contract, the other party may terminate the Contract by providing written notice to the defaulting party. This notice shall describe with sufficient detail the nature of the default. The party receiving such notice shall promptly be removed from being a Block Producer and this Contract shall be automatically terminated. 9 | 10 | ### CLAUSE NAME: Force Majeure 11 | FORCE MAJEURE. If performance of this Contract or any obligation under this Contract is prevented, restricted, or interfered with by causes beyond either party's reasonable control ("Force Majeure"), and if the party unable to carry out its obligations gives the other party prompt written notice of such event, then the obligations of the party invoking this provision shall be suspended to the extent necessary by such event. The term Force Majeure shall include, without limitation, acts of God, fire, explosion, vandalism, storm or other similar occurrence, orders or acts of military or civil authority, or by national emergencies, insurrections, riots, or wars, or strikes, lock-outs, work stoppages, or supplier failures. The excused party shall use reasonable efforts under the circumstances to avoid or remove such causes of non-performance and shall proceed to perform with reasonable dispatch whenever such causes are removed or ceased. An act or omission shall be deemed within the reasonable control of a party if committed, omitted, or caused by such party, or its employees, officers, agents, or affiliates. 12 | 13 | ### CLAUSE NAME: Dispute Resolution 14 | DISPUTE RESOLUTION. Any controversies or disputes arising out of or relating to this Contract will be resolved by binding arbitration under the default rules set forth by the EOS.IO Blockchain. The arbitrator's award will be final, and judgment may be entered upon it by any court having proper jurisdiction. 15 | 16 | ### CLAUSE NAME: Entire Agreement 17 | ENTIRE AGREEMENT. This Contract contains the entire agreement of the parties, and there are no other promises or conditions in any other agreement whether oral or written concerning the subject matter of this Contract. This Contract supersedes any prior written or oral agreements between the parties. 18 | 19 | ### CLAUSE NAME: Severability 20 | SEVERABILITY. If any provision of this Contract will be held to be invalid or unenforceable for any reason, the remaining provisions will continue to be valid and enforceable. If a court finds that any provision of this Contract is invalid or unenforceable, but that by limiting such provision it would become valid and enforceable, then such provision will be deemed to be written, construed, and enforced as so limited. 21 | 22 | ### CLAUSE NAME: Amendment 23 | AMENDMENT. This Contract may be modified or amended in writing by mutual agreement between the parties, if the writing is signed by the party obligated under the amendment. 24 | 25 | ### CLAUSE NAME: Governing Law 26 | GOVERNING LAW. This Contract shall be construed in accordance with the Maxims of Equity. 27 | 28 | ### CLAUSE NAME: Notice 29 | NOTICE. Any notice or communication required or permitted under this Contract shall be sufficiently given if delivered to a verifiable email address or to such other email address as one party may have publicly furnished in writing, or published on a broadcast contract provided by this blockchain for purposes of providing notices of this type. 30 | ### CLAUSE NAME: Waiver of Contractual Right 31 | WAIVER OF CONTRACTUAL RIGHT. The failure of either party to enforce any provision of this Contract shall not be construed as a waiver or limitation of that party's right to subsequently enforce and compel strict compliance with every provision of this Contract. 32 | 33 | ### CLAUSE NAME: Arbitrator's Fees to Prevailing Party 34 | ARBITRATOR'S FEES TO PREVAILING PARTY. In any action arising hereunder or any separate action pertaining to the validity of this Agreement, both sides shall pay half the initial cost of arbitration, and the prevailing party shall be awarded reasonable arbitrator's fees and costs. 35 | 36 | ### CLAUSE NAME: Construction and Interpretation 37 | CONSTRUCTION AND INTERPRETATION. The rule requiring construction or interpretation against the drafter is waived. The document shall be deemed as if it were drafted by both parties in a mutual effort. 38 | 39 | ### CLAUSE NAME: In Witness Whereof 40 | IN WITNESS WHEREOF, the parties hereto have caused this Agreement to be executed by themselves or their duly authorized representatives as of the date of execution, and authorized as proven by the cryptographic signature on the transaction that invokes this contract. 41 | -------------------------------------------------------------------------------- /enuplayerone/enu.token/enu.token.abi: -------------------------------------------------------------------------------- 1 | { 2 | "____comment": "This file was generated by enugenabi. DO NOT EDIT - 2018-08-22T04:57:32", 3 | "version": "enumivo::abi/1.0", 4 | "types": [{ 5 | "new_type_name": "account_name", 6 | "type": "name" 7 | }], 8 | "structs": [{ 9 | "name": "transfer", 10 | "base": "", 11 | "fields": [ 12 | {"name":"from", "type":"account_name"}, 13 | {"name":"to", "type":"account_name"}, 14 | {"name":"quantity", "type":"asset"}, 15 | {"name":"memo", "type":"string"} 16 | ] 17 | },{ 18 | "name": "create", 19 | "base": "", 20 | "fields": [ 21 | {"name":"issuer", "type":"account_name"}, 22 | {"name":"maximum_supply", "type":"asset"} 23 | ] 24 | },{ 25 | "name": "issue", 26 | "base": "", 27 | "fields": [ 28 | {"name":"to", "type":"account_name"}, 29 | {"name":"quantity", "type":"asset"}, 30 | {"name":"memo", "type":"string"} 31 | ] 32 | },{ 33 | "name": "account", 34 | "base": "", 35 | "fields": [ 36 | {"name":"balance", "type":"asset"} 37 | ] 38 | },{ 39 | "name": "currency_stats", 40 | "base": "", 41 | "fields": [ 42 | {"name":"supply", "type":"asset"}, 43 | {"name":"max_supply", "type":"asset"}, 44 | {"name":"issuer", "type":"account_name"} 45 | ] 46 | } 47 | ], 48 | "actions": [{ 49 | "name": "transfer", 50 | "type": "transfer", 51 | "ricardian_contract": "" 52 | },{ 53 | "name": "issue", 54 | "type": "issue", 55 | "ricardian_contract": "" 56 | }, { 57 | "name": "create", 58 | "type": "create", 59 | "ricardian_contract": "" 60 | } 61 | 62 | ], 63 | "tables": [{ 64 | "name": "accounts", 65 | "type": "account", 66 | "index_type": "i64", 67 | "key_names" : ["currency"], 68 | "key_types" : ["uint64"] 69 | },{ 70 | "name": "stat", 71 | "type": "currency_stats", 72 | "index_type": "i64", 73 | "key_names" : ["currency"], 74 | "key_types" : ["uint64"] 75 | } 76 | ], 77 | "ricardian_clauses": [], 78 | "abi_extensions": [] 79 | } -------------------------------------------------------------------------------- /enuplayerone/enu.token/enu.token.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @copyright defined in eos/LICENSE.txt 4 | */ 5 | 6 | #include "enu.token.hpp" 7 | 8 | namespace enumivo { 9 | 10 | void token::create( account_name issuer, 11 | asset maximum_supply ) 12 | { 13 | require_auth( _self ); 14 | 15 | auto sym = maximum_supply.symbol; 16 | enumivo_assert( sym.is_valid(), "invalid symbol name" ); 17 | enumivo_assert( maximum_supply.is_valid(), "invalid supply"); 18 | enumivo_assert( maximum_supply.amount > 0, "max-supply must be positive"); 19 | 20 | stats statstable( _self, sym.name() ); 21 | auto existing = statstable.find( sym.name() ); 22 | enumivo_assert( existing == statstable.end(), "token with symbol already exists" ); 23 | 24 | statstable.emplace( _self, [&]( auto& s ) { 25 | s.supply.symbol = maximum_supply.symbol; 26 | s.max_supply = maximum_supply; 27 | s.issuer = issuer; 28 | }); 29 | } 30 | 31 | 32 | void token::issue( account_name to, asset quantity, string memo ) 33 | { 34 | auto sym = quantity.symbol; 35 | enumivo_assert( sym.is_valid(), "invalid symbol name" ); 36 | enumivo_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 37 | 38 | auto sym_name = sym.name(); 39 | stats statstable( _self, sym_name ); 40 | auto existing = statstable.find( sym_name ); 41 | enumivo_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); 42 | const auto& st = *existing; 43 | 44 | require_auth( st.issuer ); 45 | enumivo_assert( quantity.is_valid(), "invalid quantity" ); 46 | enumivo_assert( quantity.amount > 0, "must issue positive quantity" ); 47 | 48 | enumivo_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 49 | enumivo_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); 50 | 51 | statstable.modify( st, 0, [&]( auto& s ) { 52 | s.supply += quantity; 53 | }); 54 | 55 | add_balance( st.issuer, quantity, st.issuer ); 56 | 57 | if( to != st.issuer ) { 58 | SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); 59 | } 60 | } 61 | 62 | void token::transfer( account_name from, 63 | account_name to, 64 | asset quantity, 65 | string memo ) 66 | { 67 | enumivo_assert( from != to, "cannot transfer to self" ); 68 | require_auth( from ); 69 | enumivo_assert( is_account( to ), "to account does not exist"); 70 | auto sym = quantity.symbol.name(); 71 | stats statstable( _self, sym ); 72 | const auto& st = statstable.get( sym ); 73 | 74 | require_recipient( from ); 75 | require_recipient( to ); 76 | 77 | enumivo_assert( quantity.is_valid(), "invalid quantity" ); 78 | enumivo_assert( quantity.amount > 0, "must transfer positive quantity" ); 79 | enumivo_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 80 | enumivo_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 81 | 82 | 83 | sub_balance( from, quantity ); 84 | add_balance( to, quantity, from ); 85 | } 86 | 87 | void token::sub_balance( account_name owner, asset value ) { 88 | accounts from_acnts( _self, owner ); 89 | 90 | const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); 91 | enumivo_assert( from.balance.amount >= value.amount, "overdrawn balance" ); 92 | 93 | 94 | if( from.balance.amount == value.amount ) { 95 | from_acnts.erase( from ); 96 | } else { 97 | from_acnts.modify( from, owner, [&]( auto& a ) { 98 | a.balance -= value; 99 | }); 100 | } 101 | } 102 | 103 | void token::add_balance( account_name owner, asset value, account_name ram_payer ) 104 | { 105 | accounts to_acnts( _self, owner ); 106 | auto to = to_acnts.find( value.symbol.name() ); 107 | if( to == to_acnts.end() ) { 108 | to_acnts.emplace( ram_payer, [&]( auto& a ){ 109 | a.balance = value; 110 | }); 111 | } else { 112 | to_acnts.modify( to, 0, [&]( auto& a ) { 113 | a.balance += value; 114 | }); 115 | } 116 | } 117 | 118 | } /// namespace enumivo 119 | 120 | ENUMIVO_ABI( enumivo::token, (create)(issue)(transfer) ) 121 | -------------------------------------------------------------------------------- /enuplayerone/enu.token/enu.token.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @copyright defined in eos/LICENSE.txt 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace enumivosystem { 13 | class system_contract; 14 | } 15 | 16 | namespace enumivo { 17 | 18 | using std::string; 19 | 20 | class token : public contract { 21 | public: 22 | token( account_name self ):contract(self){} 23 | 24 | void create( account_name issuer, 25 | asset maximum_supply); 26 | 27 | void issue( account_name to, asset quantity, string memo ); 28 | 29 | void transfer( account_name from, 30 | account_name to, 31 | asset quantity, 32 | string memo ); 33 | 34 | 35 | inline asset get_supply( symbol_name sym )const; 36 | 37 | inline asset get_balance( account_name owner, symbol_name sym )const; 38 | 39 | private: 40 | struct account { 41 | asset balance; 42 | 43 | uint64_t primary_key()const { return balance.symbol.name(); } 44 | }; 45 | 46 | struct currency_stats { 47 | asset supply; 48 | asset max_supply; 49 | account_name issuer; 50 | 51 | uint64_t primary_key()const { return supply.symbol.name(); } 52 | }; 53 | 54 | typedef enumivo::multi_index accounts; 55 | typedef enumivo::multi_index stats; 56 | 57 | void sub_balance( account_name owner, asset value ); 58 | void add_balance( account_name owner, asset value, account_name ram_payer ); 59 | 60 | public: 61 | struct transfer_args { 62 | account_name from; 63 | account_name to; 64 | asset quantity; 65 | string memo; 66 | }; 67 | }; 68 | 69 | asset token::get_supply( symbol_name sym )const 70 | { 71 | stats statstable( _self, sym ); 72 | const auto& st = statstable.get( sym ); 73 | return st.supply; 74 | } 75 | 76 | asset token::get_balance( account_name owner, symbol_name sym )const 77 | { 78 | accounts accountstable( _self, owner ); 79 | const auto& ac = accountstable.get( sym ); 80 | return ac.balance; 81 | } 82 | 83 | } /// namespace enumivo 84 | -------------------------------------------------------------------------------- /enuplayerone/enu.token/enu.token.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/enuplayerone/enu.token/enu.token.wasm -------------------------------------------------------------------------------- /enuplayerone/enu_init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | enucli wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 4 | 5 | # assume you have imported the testers' keys 6 | enucli wallet import --private-key 5KKUS3oXbTQpmL1TqYm8xo8Zy9XNQ6DwwJwuUzAzo2CBRqSRweV 7 | enucli wallet import --private-key 5JVVQpGNWLz3nUcPDjeixSH6mi2pRW6da9ErLWK3RaMipWJox37 8 | enucli wallet import --private-key 5K9ZQFXzeesmjdUqPQytg1KKiDGTWSDsW5jQHqUZttVi9VLwrJX 9 | enucli wallet import --private-key 5JcxRgm2WkD5x482BG3gjE4kJde9CqMutPcq3k2UYYajuNkR5wN 10 | enucli wallet import --private-key 5JrsSNfzM5YDQmdkYfgRBQtSQ9WZccM6n7CRGrBE9g7CrG6NHhM 11 | enucli wallet import --private-key 5JYAkZt781wVvtxg3Y41hBRT2SSxEVeNTiyJKKrBXTMGCwKQJCx 12 | enucli wallet import --private-key 5JSHN5z385ZEikDzdrU1ixZp1XYoNw7m8X9s1LYaUWxt3Y3gbDG 13 | enucli wallet import --private-key 5KGx9WDVGWeXU7twpQ9dRsJUEsk4tf7b4UcLEYT8JANJyeiUsyD 14 | enucli wallet import --private-key 5KCa3Pvq5APMZYCz3qABisnDA1sUtYiKwinLWU7aHqv2kU7BQYb 15 | enucli wallet import --private-key 5KA7efGfZdFpgEX37uPiDQAarfacs5X5W6GUzk9kdQzhrSZJiW9 16 | enucli wallet import --private-key 5JTGHQaHSXz6HCqt4QCtabfptz7pCrpmMMLdZD7nbUSRtEvEcuL 17 | 18 | 19 | # enu.token = ENU87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E=KEY:5KKUS3oXbTQpmL1TqYm8xo8Zy9XNQ6DwwJwuUzAzo2CBRqSRweV 20 | enucli create account enumivo enu.token ENU87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E ENU87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E 21 | enucli set contract enu.token ./enu.token -p enu.token 22 | 23 | enucli push action enu.token create '[ "enu.token", "1000000000.0000 ENU"]' -p enu.token 24 | enucli push action enu.token issue '[ "enu.token", "1000000000.0000 ENU", "initial supply" ]' -p enu.token 25 | 26 | 27 | # testuseraaaa = ENU7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm=KEY:5JVVQpGNWLz3nUcPDjeixSH6mi2pRW6da9ErLWK3RaMipWJox37 28 | enucli create account enumivo testuseraaaa ENU7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm ENU7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm 29 | # testuseraaab = ENU6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo=KEY:5K9ZQFXzeesmjdUqPQytg1KKiDGTWSDsW5jQHqUZttVi9VLwrJX 30 | enucli create account enumivo testuseraaab ENU6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo ENU6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo 31 | # testuseraaac = ENU6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW=KEY:5JcxRgm2WkD5x482BG3gjE4kJde9CqMutPcq3k2UYYajuNkR5wN 32 | enucli create account enumivo testuseraaac ENU6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW ENU6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW 33 | # testuseraaad = ENU7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU=KEY:5JrsSNfzM5YDQmdkYfgRBQtSQ9WZccM6n7CRGrBE9g7CrG6NHhM 34 | enucli create account enumivo testuseraaad ENU7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU ENU7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU 35 | # testuseraaae = ENU8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n=KEY:5JYAkZt781wVvtxg3Y41hBRT2SSxEVeNTiyJKKrBXTMGCwKQJCx 36 | enucli create account enumivo testuseraaae ENU8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n ENU8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n 37 | # testuseraaaf = ENU696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a=KEY:5JSHN5z385ZEikDzdrU1ixZp1XYoNw7m8X9s1LYaUWxt3Y3gbDG 38 | enucli create account enumivo testuseraaaf ENU696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a ENU696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a 39 | # testuseraaag = ENU5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg=KEY:5KGx9WDVGWeXU7twpQ9dRsJUEsk4tf7b4UcLEYT8JANJyeiUsyD 40 | enucli create account enumivo testuseraaag ENU5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg ENU5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg 41 | # testuseraaah = ENU5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH=KEY:5KCa3Pvq5APMZYCz3qABisnDA1sUtYiKwinLWU7aHqv2kU7BQYb 42 | enucli create account enumivo testuseraaah ENU5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH ENU5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH 43 | # testuseraaai = ENU6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ=KEY:5KA7efGfZdFpgEX37uPiDQAarfacs5X5W6GUzk9kdQzhrSZJiW9 44 | enucli create account enumivo testuseraaai ENU6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ ENU6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ 45 | # testuseraaaj = ENU5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd=KEY:5JTGHQaHSXz6HCqt4QCtabfptz7pCrpmMMLdZD7nbUSRtEvEcuL 46 | enucli create account enumivo testuseraaaj ENU5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd ENU5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd 47 | 48 | enucli transfer enu.token testuseraaaa "100000 ENU" "test" -p enu.token 49 | enucli transfer enu.token testuseraaab "100000 ENU" "test" -p enu.token 50 | enucli transfer enu.token testuseraaac "100000 ENU" "test" -p enu.token 51 | enucli transfer enu.token testuseraaad "100000 ENU" "test" -p enu.token 52 | enucli transfer enu.token testuseraaae "100000 ENU" "test" -p enu.token 53 | enucli transfer enu.token testuseraaaf "100000 ENU" "test" -p enu.token 54 | enucli transfer enu.token testuseraaag "100000 ENU" "test" -p enu.token 55 | enucli transfer enu.token testuseraaah "100000 ENU" "test" -p enu.token 56 | enucli transfer enu.token testuseraaai "100000 ENU" "test" -p enu.token 57 | enucli transfer enu.token testuseraaaj "100000 ENU" "test" -p enu.token 58 | 59 | -------------------------------------------------------------------------------- /enuplayerone/playerone.abi: -------------------------------------------------------------------------------- 1 | { 2 | "____comment": "This file was generated by enugenabi. DO NOT EDIT - 2018-08-23T04:03:01", 3 | "version": "enumivo::abi/1.0", 4 | "types": [], 5 | "structs": [{ 6 | "name": "game", 7 | "base": "", 8 | "fields": [{ 9 | "name": "gameid", 10 | "type": "name" 11 | },{ 12 | "name": "reserve", 13 | "type": "asset" 14 | },{ 15 | "name": "insure", 16 | "type": "asset" 17 | },{ 18 | "name": "max_supply", 19 | "type": "asset" 20 | },{ 21 | "name": "supply", 22 | "type": "asset" 23 | },{ 24 | "name": "balance", 25 | "type": "asset" 26 | },{ 27 | "name": "circulation", 28 | "type": "asset" 29 | },{ 30 | "name": "burn", 31 | "type": "asset" 32 | },{ 33 | "name": "staked", 34 | "type": "asset" 35 | },{ 36 | "name": "fee", 37 | "type": "asset" 38 | },{ 39 | "name": "reward", 40 | "type": "asset" 41 | },{ 42 | "name": "next_refer", 43 | "type": "name" 44 | },{ 45 | "name": "player_one", 46 | "type": "name" 47 | },{ 48 | "name": "start_time", 49 | "type": "uint64" 50 | },{ 51 | "name": "reward_time", 52 | "type": "uint64" 53 | } 54 | ] 55 | },{ 56 | "name": "user", 57 | "base": "", 58 | "fields": [{ 59 | "name": "gameid", 60 | "type": "name" 61 | },{ 62 | "name": "name", 63 | "type": "name" 64 | },{ 65 | "name": "parent", 66 | "type": "name" 67 | },{ 68 | "name": "reward", 69 | "type": "asset" 70 | },{ 71 | "name": "last_action", 72 | "type": "uint64" 73 | },{ 74 | "name": "refer", 75 | "type": "uint64" 76 | },{ 77 | "name": "quota", 78 | "type": "uint64" 79 | },{ 80 | "name": "discount", 81 | "type": "uint32" 82 | } 83 | ] 84 | },{ 85 | "name": "refer", 86 | "base": "", 87 | "fields": [{ 88 | "name": "name", 89 | "type": "name" 90 | } 91 | ] 92 | },{ 93 | "name": "invitation", 94 | "base": "", 95 | "fields": [{ 96 | "name": "to", 97 | "type": "name" 98 | },{ 99 | "name": "from", 100 | "type": "name" 101 | } 102 | ] 103 | } 104 | ], 105 | "actions": [], 106 | "tables": [{ 107 | "name": "game", 108 | "index_type": "i64", 109 | "key_names": [ 110 | "gameid" 111 | ], 112 | "key_types": [ 113 | "name" 114 | ], 115 | "type": "game" 116 | },{ 117 | "name": "userinfo", 118 | "index_type": "i64", 119 | "key_names": [ 120 | "gameid" 121 | ], 122 | "key_types": [ 123 | "name" 124 | ], 125 | "type": "user" 126 | },{ 127 | "name": "refers", 128 | "index_type": "i64", 129 | "key_names": [ 130 | "name" 131 | ], 132 | "key_types": [ 133 | "name" 134 | ], 135 | "type": "refer" 136 | },{ 137 | "name": "invitations", 138 | "index_type": "i64", 139 | "key_names": [ 140 | "to" 141 | ], 142 | "key_types": [ 143 | "name" 144 | ], 145 | "type": "invitation" 146 | } 147 | ], 148 | "ricardian_clauses": [], 149 | "error_messages": [], 150 | "abi_extensions": [] 151 | } -------------------------------------------------------------------------------- /enuplayerone/playerone.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Orange on 2018/8/8. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define GAME_SYMBOL S(4, CGT) 10 | #define TOKEN_CONTRACT N(enu.token) 11 | #define GAME_TOKEN_CONTRACT N(playeroneiss) 12 | #define BURN_ACCOUNT N(blackholeeos) 13 | #define FEE_ACCOUNT N(playeronefee) 14 | 15 | typedef double real_type; 16 | 17 | using namespace enumivo; 18 | using namespace std; 19 | 20 | class playerone: public contract { 21 | public: 22 | const int64_t _B = 5ll; 23 | const int64_t _A = 100ll - _B * 2; 24 | const int64_t _L = 2500000ll; 25 | const int64_t _D = _L / 4; 26 | const int64_t _INITIAL_PRICE = 100ll; 27 | const int64_t _MAX_SUPPLY_TIMES = 10ll; 28 | const int64_t _GAME_INIT_TIME = 1535112488ll; // 2018/8/24 20:8:8 29 | const int64_t _GAME_PRESALE_TIME = _GAME_INIT_TIME + 2 * 60 * 60ll; 30 | const int64_t _ACTION_COOL_DOWN = 1ll; 31 | const int64_t _REWARD_COOL_DOWN = 24 * 60 * 60ll; 32 | const int64_t _UNIT = 10000ll; 33 | const int64_t _MAX_IN_PRESALE = 10 * _UNIT; 34 | const int64_t _REFER_PRICE = _UNIT; 35 | 36 | playerone(account_name self) 37 | : contract(self), 38 | _game(_self, _self), 39 | refers(_self, _self), 40 | invitations(_self, _self) 41 | { 42 | // Create a new game if not exists 43 | auto game_itr = _game.begin(); 44 | if (game_itr == _game.end()) 45 | { 46 | game_itr = _game.emplace(_self, [&](auto& g){ 47 | g.gameid = _self; 48 | g.max_supply = asset(_L * _MAX_SUPPLY_TIMES * _UNIT, GAME_SYMBOL); 49 | g.start_time = _GAME_INIT_TIME; 50 | g.reward_time = _GAME_PRESALE_TIME + _REWARD_COOL_DOWN; 51 | }); 52 | } 53 | user_table userinfo(_self, FEE_ACCOUNT); 54 | auto user_itr = userinfo.find(game_itr->gameid); 55 | if(user_itr == userinfo.end()){ 56 | user_itr = userinfo.emplace(_self, [&](auto& u){ 57 | u.gameid = game_itr->gameid; 58 | u.name = FEE_ACCOUNT; 59 | u.parent = FEE_ACCOUNT; 60 | u.refer = 100; 61 | u.discount = 1; 62 | }); 63 | } 64 | 65 | auto refer_itr = refers.find(FEE_ACCOUNT); 66 | if(refer_itr == refers.end() && user_itr->refer > 0){ 67 | refer_itr = refers.emplace(_self, [&](auto& r){ 68 | r.name = FEE_ACCOUNT; 69 | }); 70 | } 71 | }; 72 | 73 | void enu_token_transfer(account_name from, account_name to, asset quantity, string memo){ 74 | require_auth(from); 75 | if (from == _self || to != _self) { 76 | return; 77 | } 78 | enumivo_assert(quantity.is_valid(), "invalid token transfer"); 79 | enumivo_assert(quantity.symbol == CORE_SYMBOL, "unexpected asset symbol input"); 80 | 81 | transfer(from, to, quantity, memo); 82 | }; 83 | 84 | void game_token_transfer(account_name from, account_name to, asset quantity, string memo){ 85 | require_auth(from); 86 | if (from == _self || to != _self) { 87 | return; 88 | } 89 | enumivo_assert(quantity.is_valid(), "invalid token transfer"); 90 | enumivo_assert(quantity.symbol == GAME_SYMBOL, "unexpected asset symbol input"); 91 | 92 | transfer(from, to, quantity, memo); 93 | }; 94 | 95 | void transfer(account_name from, account_name to, asset quantity, string memo){ 96 | require_auth(from); 97 | if (from == _self || to != _self) { 98 | return; 99 | } 100 | enumivo_assert(quantity.is_valid(), "invalid token transfer"); 101 | 102 | auto game_itr = _game.begin(); 103 | 104 | if(quantity.symbol == CORE_SYMBOL){ 105 | if(quantity.amount == 1ll){ 106 | if(memo.size() <= 0 || memo.size() > 12){ 107 | // 用户通过向合约转账0.0001ENU取回推荐人奖金 108 | claim_fee(from); 109 | } else { 110 | // 预售前可以通过发送邀请获得免费的预售额度。发送邀请的方式为:向合约转账0.0001ENU并且备注未注册的ENU账号,将成为他的推荐上级(需要消耗少量RAM),每个邀请增加1ENU预售额度(邀请码减少一个,邀请获得两个,总额度的增加一个),单个账号不超过50ENU 111 | string from_str = name_to_string(from); 112 | account_name to_user = string_to_name(memo.c_str()); 113 | 114 | action( 115 | permission_level{_self, N(active)}, 116 | TOKEN_CONTRACT, N(transfer), 117 | make_tuple(_self, to_user, quantity, from_str + "邀请您参与头号玩家,通过邀请码注册有机会减少一半的手续费。网址: http://eosplayer.one/#/?ref=" + from_str)) 118 | .send(); 119 | 120 | auto invitation_itr = invitations.find(to_user); 121 | user_table to_userinfo(_self, to_user); 122 | auto to_user_itr = to_userinfo.find(game_itr->gameid); 123 | user_table from_userinfo(_self, from); 124 | auto from_user_itr = from_userinfo.find(game_itr->gameid); 125 | if(from_user_itr != from_userinfo.end() && invitation_itr == invitations.end() && to_user_itr == to_userinfo.end()){ 126 | invitation_itr = invitations.emplace(from, [&](auto& i){ 127 | i.to = to_user; 128 | i.from = from; 129 | }); 130 | if(from_user_itr->refer > 0){ 131 | from_userinfo.modify(from_user_itr, from, [&](auto& u){ 132 | u.refer --; 133 | }); 134 | to_user_itr = to_userinfo.emplace(from, [&](auto& u){ 135 | u.gameid = game_itr->gameid; 136 | u.name = to_user; 137 | u.parent = from; 138 | u.discount = 1; 139 | }); 140 | if(from_user_itr->quota < 200 && now() < _GAME_INIT_TIME ){ 141 | from_userinfo.modify(from_user_itr, from, [&](auto& u){ 142 | u.quota += 1; 143 | }); 144 | } 145 | } 146 | } 147 | } 148 | } else if(quantity.amount == 2ll){ 149 | // 头号通过向合约转账0.0002ENU获得头号奖金 150 | // 奖励冷却时间是24小时,每次获得头号奖金池的10%,单次奖金得超过10ENU 151 | // 如果头号位置更替,奖励冷却时间将重置 152 | claim_reward(from); 153 | } else if(quantity.amount == 3ll){ 154 | // 头号通过向合约转账0.0003ENU解除抵押,将消耗抵押CGT的10% 155 | unstake(from); 156 | } else if(memo == "deposit"){ 157 | // 通过向合约转账备注deposit存入ENU,用于购买邀请码,预售结束前获得等量预售额外额度,以及之后生态接入 158 | // 存入的ENU将分红给所有流通CGT 159 | // 购买邀请码将有机会获得新用户交易手续费的分红 160 | deposit(from, quantity); 161 | } else if(memo == "reward"){ 162 | // 通过向合约转账备注reward存入头号奖励 163 | // 存入的ENU将鼓励玩家竞选头号 164 | deposit_reward(quantity); 165 | } else { 166 | enumivo_assert( now() >= _GAME_INIT_TIME, "游戏还没有开始,开始时间是:2018/8/24 20:8:8"); 167 | if( now() < _GAME_PRESALE_TIME ){ 168 | user_table userinfo(_self, from); 169 | auto user_itr = userinfo.find(game_itr->gameid); 170 | // 预售结束前可以通过存入ENU获得等量的预售额度,存入的ENU对全部流通CGT分红,不可退回。相当于两倍的价格参与预售 171 | // 预售中每次买入会有平均30秒的冷却时间,连续两次买入间隔越短,下一次买入冷却时间越长,t = 225 / (dt + 1),t为冷却时间,dt是冷却后等待的时间。预售结束之后冷却时间降为1秒。 172 | if(user_itr == userinfo.end() || quantity.amount > user_itr->quota * _UNIT + _MAX_IN_PRESALE || quantity.amount <= _MAX_IN_PRESALE ){ 173 | enumivo_assert( quantity.amount >= _UNIT && quantity.amount <= _MAX_IN_PRESALE, "预售额外份额不足,请单次购买 1 - 10 ENU"); 174 | } else { 175 | // 超出10ENU的部分将从预售额度里面扣除 176 | asset quota = quantity; 177 | quota -= asset(_MAX_IN_PRESALE, CORE_SYMBOL); 178 | enumivo_assert( user_itr->quota * _UNIT >= quota.amount, "预售额外份额不足,请单次购买 1 - 10 ENU"); 179 | userinfo.modify(user_itr, from, [&](auto& u){ 180 | u.quota -= quota.amount / _UNIT; 181 | }); 182 | } 183 | } 184 | buy(from, quantity, memo); 185 | } 186 | } else if(quantity.symbol == GAME_SYMBOL) { 187 | enumivo_assert( now() >= _GAME_PRESALE_TIME, "预售阶段不能够销毁、抵押、出售CGT"); 188 | if(memo == "burn"){ 189 | burn(from, quantity); 190 | } else if(memo == "stake"){ 191 | // 通过向合约转账足够的CGT并且备注stake竞争头号 192 | stake(from, quantity); 193 | } else { 194 | sell(from, quantity, memo); 195 | } 196 | } else { 197 | enumivo_assert(false, "不要转入其他代币资产"); 198 | } 199 | }; 200 | 201 | void buy(account_name account, asset quantity, string memo){ 202 | enumivo_assert(quantity.amount >= _UNIT && quantity.amount <= 100 * _UNIT, "买入CGT区间为 1 - 100 ENU"); 203 | 204 | asset exchange_unit = asset(20 * _UNIT, CORE_SYMBOL); 205 | int64_t times = (quantity / exchange_unit) + 1; 206 | asset deposited_eos = asset(0, CORE_SYMBOL); 207 | asset insured_eos = asset(0, CORE_SYMBOL); 208 | asset exchanged_eos = asset(0, CORE_SYMBOL); 209 | asset issued_eos = asset(0, CORE_SYMBOL); 210 | auto game_itr = _game.begin(); 211 | user_table userinfo(_self, account); 212 | auto user_itr = userinfo.find(game_itr->gameid); 213 | if(user_itr == userinfo.end()){ 214 | new_user(account, memo, account); 215 | user_itr = userinfo.find(game_itr->gameid); 216 | } else { 217 | uint64_t now_action = now(); 218 | enumivo_assert( now_action >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 219 | if( now_action < _GAME_PRESALE_TIME){ 220 | now_action += 225ll / (now_action - user_itr->last_action + 1); 221 | } 222 | userinfo.modify(user_itr, account, [&](auto& u) { 223 | u.last_action = now_action; 224 | }); 225 | } 226 | 227 | asset fee = quantity; 228 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (first round up) 229 | 230 | asset quant_after_fee = quantity; 231 | quant_after_fee -= fee; 232 | 233 | collect_fee(account, fee); 234 | 235 | fee.amount = quant_after_fee.amount; 236 | if(user_itr->discount == 0){ 237 | fee.amount = (fee.amount + 49) / 50; /// 2% fee (second round up) 238 | } else { 239 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (discount half of the fee with a refer) 240 | } 241 | 242 | asset action_total_fee = fee; 243 | quant_after_fee -= fee; 244 | 245 | asset remain_eos = quant_after_fee; 246 | asset transfer_token = asset(0, GAME_SYMBOL); 247 | asset issue_token = asset(0, GAME_SYMBOL); 248 | asset reserve_balance = game_itr->reserve; 249 | asset token_supply = game_itr->supply; 250 | asset token_balance = game_itr->balance; 251 | asset circulation = token_supply - token_balance; 252 | real_type crr; 253 | real_type token_price; 254 | for(int64_t i = 0; i < times; i++){ 255 | if(remain_eos <= asset(0, CORE_SYMBOL)){ 256 | break; 257 | } 258 | if(exchange_unit > remain_eos){ 259 | exchange_unit = remain_eos; 260 | } 261 | if(circulation > asset(100000 * _UNIT, GAME_SYMBOL) && token_balance > asset(0, GAME_SYMBOL)){ 262 | crr = _crr(circulation); 263 | token_price = real_type(reserve_balance.amount) / (real_type(circulation.amount) * crr); 264 | asset token_per_exchange = asset(real_type(exchange_unit.amount) / token_price, GAME_SYMBOL); 265 | crr = _crr(circulation + token_per_exchange); 266 | token_price = real_type((reserve_balance + exchange_unit).amount) / (real_type(circulation.amount) * crr); 267 | token_per_exchange = asset(real_type(exchange_unit.amount) / token_price, GAME_SYMBOL); 268 | if(token_balance >= token_per_exchange){ 269 | circulation += token_per_exchange; 270 | token_balance -= token_per_exchange; 271 | transfer_token += token_per_exchange; 272 | deposited_eos += exchange_unit; 273 | remain_eos -= exchange_unit; 274 | exchanged_eos += exchange_unit; 275 | reserve_balance += exchange_unit; 276 | } else { 277 | token_per_exchange = token_balance; 278 | crr = _crr(circulation + token_per_exchange); 279 | token_price = real_type((reserve_balance + exchange_unit).amount) / (real_type(circulation.amount) * crr); 280 | circulation += token_per_exchange; 281 | token_balance -= token_per_exchange; 282 | transfer_token += token_per_exchange; 283 | asset to_deposit_eos = asset(token_price * real_type(token_per_exchange.amount), CORE_SYMBOL); 284 | deposited_eos += to_deposit_eos; 285 | remain_eos -= to_deposit_eos; 286 | exchanged_eos += to_deposit_eos; 287 | reserve_balance += to_deposit_eos; 288 | } 289 | enumivo_assert(token_price >= real_type(0.0), "invalid token price"); 290 | } else { 291 | crr = _crr(circulation); 292 | asset to_issue_eos = asset(real_type(exchange_unit.amount) * crr, exchange_unit.symbol); 293 | real_type INITIAL_PRICE(_INITIAL_PRICE); 294 | real_type UNIT(_UNIT); 295 | INITIAL_PRICE = INITIAL_PRICE / UNIT; 296 | asset token_per_issue = asset(real_type(to_issue_eos.amount) / INITIAL_PRICE, GAME_SYMBOL); 297 | circulation += token_per_issue; 298 | issue_token += token_per_issue; 299 | deposited_eos += to_issue_eos; 300 | insured_eos += exchange_unit - to_issue_eos; 301 | remain_eos -= exchange_unit; 302 | issued_eos += exchange_unit; 303 | reserve_balance += to_issue_eos; 304 | } 305 | } 306 | 307 | asset refund_eos = quant_after_fee - deposited_eos - insured_eos; 308 | 309 | enumivo_assert(transfer_token <= game_itr->balance, "insufficient token balance"); 310 | enumivo_assert(refund_eos == remain_eos && refund_eos >= asset(0, CORE_SYMBOL) && refund_eos <= quant_after_fee, "invalid eos refund"); 311 | enumivo_assert(deposited_eos >= asset(0, CORE_SYMBOL) && insured_eos >= asset(0, CORE_SYMBOL), "eos deposit or insure must be positive"); 312 | enumivo_assert(transfer_token >= asset(0, GAME_SYMBOL) && issue_token >= asset(0, GAME_SYMBOL), "transfer and issue token should not be negetive"); 313 | enumivo_assert(exchanged_eos + issued_eos == deposited_eos + insured_eos && quant_after_fee - remain_eos == deposited_eos + insured_eos, "eos not equal"); 314 | enumivo_assert(transfer_token + issue_token >= asset(_UNIT, GAME_SYMBOL) && transfer_token + issue_token <= asset(10000 * _UNIT, GAME_SYMBOL), "transfer and issue token must in range 1 - 10000"); 315 | 316 | _game.modify(game_itr, 0, [&](auto& g) { 317 | g.reserve += deposited_eos; 318 | g.insure += insured_eos + fee / 2; 319 | g.reward += action_total_fee - fee / 2; 320 | g.supply += issue_token; 321 | g.balance = token_balance; 322 | g.circulation = circulation; 323 | }); 324 | 325 | if(refund_eos > asset(0, CORE_SYMBOL)){ 326 | _game.modify(game_itr, account, [&](auto& g){ 327 | g.fee += refund_eos; 328 | }); 329 | userinfo.modify(user_itr, account, [&](auto& u){ 330 | u.reward += refund_eos; 331 | }); 332 | } 333 | 334 | if(transfer_token > asset(0, GAME_SYMBOL)){ 335 | action( 336 | permission_level{_self, N(active)}, 337 | GAME_TOKEN_CONTRACT, N(transfer), 338 | make_tuple(_self, account, transfer_token, string("购买CGT,感谢您支持头号玩家。 网址: http://eosplayer.one"))) 339 | .send(); 340 | } 341 | 342 | if(issue_token > asset(0, GAME_SYMBOL)){ 343 | action( 344 | permission_level{_self, N(active)}, 345 | GAME_TOKEN_CONTRACT, N(issue), 346 | make_tuple(account, issue_token, string("发行新CGT,感谢您支持头号玩家。 网址: http://eosplayer.one"))) 347 | .send(); 348 | } 349 | } 350 | 351 | void sell(account_name account, asset quantity, string memo){ 352 | enumivo_assert(quantity.amount >= _UNIT && quantity.amount <= 10000 * _UNIT, "卖出CGT区间为 1 - 10000 CGT"); 353 | asset exchange_unit = asset(2000 * _UNIT, GAME_SYMBOL); 354 | asset remain_asset = quantity; 355 | int64_t times = (quantity / exchange_unit) + 1; 356 | asset transfer_eos = asset(0, CORE_SYMBOL); 357 | auto game_itr = _game.begin(); 358 | asset reserve_balance = game_itr->reserve; 359 | asset token_supply = game_itr->supply; 360 | asset token_balance = game_itr->balance; 361 | asset circulation = token_supply - token_balance; 362 | real_type crr; 363 | real_type token_price; 364 | 365 | for(int64_t i = 0; i < times; i++){ 366 | if(remain_asset <= asset(0, GAME_SYMBOL)){ 367 | break; 368 | } 369 | if(exchange_unit > remain_asset){ 370 | exchange_unit = remain_asset; 371 | } 372 | crr = _crr(circulation); 373 | token_price = real_type(reserve_balance.amount) / (real_type(circulation.amount) * crr); 374 | asset eos_per_exchange = asset(real_type(exchange_unit.amount) * token_price, CORE_SYMBOL); 375 | reserve_balance -= eos_per_exchange; 376 | if(reserve_balance < asset(0, CORE_SYMBOL)){ 377 | enumivo_assert(false, "insufficient reserve eos"); 378 | } 379 | token_price = reserve_balance.amount / (circulation.amount * crr); 380 | eos_per_exchange = asset(real_type(exchange_unit.amount) * token_price, CORE_SYMBOL); 381 | transfer_eos += eos_per_exchange; 382 | circulation -= exchange_unit; 383 | remain_asset -= exchange_unit; 384 | token_balance += exchange_unit; 385 | 386 | enumivo_assert(token_price >= real_type(0.0), "invalid token price"); 387 | } 388 | 389 | enumivo_assert(transfer_eos <= asset(100 * _UNIT, CORE_SYMBOL) && transfer_eos >= asset(_UNIT, CORE_SYMBOL), "卖出CGT区间为 1 - 100 ENU"); 390 | enumivo_assert(remain_asset >= asset(0, GAME_SYMBOL) && quantity >= remain_asset, "remain asset is invalid"); 391 | enumivo_assert(quantity - remain_asset == token_balance - game_itr->balance, "exchange asset is not equal"); 392 | enumivo_assert(game_itr->reserve >= transfer_eos, "insufficient reserve eos"); 393 | 394 | user_table userinfo(_self, account); 395 | auto user_itr = userinfo.find(game_itr->gameid); 396 | if(user_itr == userinfo.end()){ 397 | new_user(account, memo, account); 398 | user_itr = userinfo.find(game_itr->gameid); 399 | } else { 400 | enumivo_assert( now() >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 401 | userinfo.modify(user_itr, account, [&](auto& u) { 402 | u.last_action = now(); 403 | }); 404 | } 405 | 406 | asset fee = transfer_eos; 407 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (first round up) 408 | asset quant_after_fee = transfer_eos; 409 | quant_after_fee -= fee; 410 | 411 | _game.modify(game_itr, 0, [&](auto& g) { 412 | g.reserve -= transfer_eos; 413 | g.balance = token_balance; 414 | g.circulation = circulation; 415 | }); 416 | 417 | collect_fee(account, fee); 418 | 419 | fee.amount = quant_after_fee.amount; 420 | if(user_itr->discount == 0){ 421 | fee.amount = (fee.amount + 49) / 50; /// 2% fee (second round up) 422 | } else { 423 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (discount half of the fee with a refer) 424 | } 425 | 426 | asset action_total_fee = fee; 427 | quant_after_fee -= fee; 428 | 429 | _game.modify(game_itr, 0, [&](auto& g) { 430 | g.insure += fee / 2; 431 | g.reward += action_total_fee - fee / 2; 432 | }); 433 | 434 | if(remain_asset > asset(0, GAME_SYMBOL)){ 435 | action( 436 | permission_level{_self, N(active)}, 437 | GAME_TOKEN_CONTRACT, N(transfer), 438 | make_tuple(_self, account, remain_asset, string("退回多余的CGT。 网址: http://eosplayer.one"))) 439 | .send(); 440 | } 441 | 442 | if(quant_after_fee > asset(0, CORE_SYMBOL)){ 443 | action( 444 | permission_level{_self, N(active)}, 445 | TOKEN_CONTRACT, N(transfer), 446 | make_tuple(_self, account, quant_after_fee, string("卖出CGT获得ENU。 网址: http://eosplayer.one"))) 447 | .send(); 448 | } 449 | } 450 | 451 | void burn(account_name account, asset quantity){ 452 | enumivo_assert(quantity.amount >= _UNIT && quantity.amount <= 10000 * _UNIT, "销毁CGT的区间为 1 - 10000 CGT"); 453 | 454 | auto game_itr = _game.begin(); 455 | asset insure_balance = game_itr->insure; 456 | asset token_supply = game_itr->supply; 457 | asset token_balance = game_itr->balance; 458 | asset circulation = token_supply - token_balance; 459 | real_type token_price = real_type(insure_balance.amount) / real_type(circulation.amount); 460 | asset transfer_eos = asset(token_price * real_type(quantity.amount), CORE_SYMBOL); 461 | 462 | enumivo_assert(transfer_eos <= asset(100 * _UNIT, CORE_SYMBOL) && transfer_eos >= asset(_UNIT, CORE_SYMBOL), "销毁CGT的区间为 1 - 100 ENU"); 463 | enumivo_assert(insure_balance >= transfer_eos, "insufficient insure eos"); 464 | 465 | user_table userinfo(_self, account); 466 | auto user_itr = userinfo.find(game_itr->gameid); 467 | if(user_itr == userinfo.end()){ 468 | new_user(account, string(""), account); 469 | user_itr = userinfo.find(game_itr->gameid); 470 | } else { 471 | enumivo_assert( now() >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 472 | userinfo.modify(user_itr, account, [&](auto& u) { 473 | u.last_action = now(); 474 | }); 475 | } 476 | 477 | asset fee = transfer_eos; 478 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (round up) 479 | asset quant_after_fee = transfer_eos; 480 | quant_after_fee -= fee; 481 | 482 | collect_fee(account, fee); 483 | 484 | _game.modify(game_itr, 0, [&](auto& g) { 485 | g.insure -= transfer_eos; 486 | g.supply -= quantity; 487 | g.circulation -= quantity; 488 | g.burn += quantity; 489 | }); 490 | 491 | if(quantity > asset(0, GAME_SYMBOL)){ 492 | action( 493 | permission_level{_self, N(active)}, 494 | GAME_TOKEN_CONTRACT, N(transfer), 495 | make_tuple(_self, BURN_ACCOUNT, quantity, string("销毁CGT到黑洞账号"))) 496 | .send(); 497 | } 498 | 499 | if(quant_after_fee > asset(0, CORE_SYMBOL)){ 500 | action( 501 | permission_level{_self, N(active)}, 502 | TOKEN_CONTRACT, N(transfer), 503 | make_tuple(_self, account, quant_after_fee, string("销毁CGT获得ENU。 网址: http://eosplayer.one"))) 504 | .send(); 505 | } 506 | } 507 | 508 | void deposit(account_name account, asset quantity){ 509 | auto game_itr = _game.begin(); 510 | user_table userinfo(_self, account); 511 | auto user_itr = userinfo.find(game_itr->gameid); 512 | user_table fee_userinfo(_self, FEE_ACCOUNT); 513 | auto fee_user_itr = fee_userinfo.find(game_itr->gameid); 514 | if(quantity.amount >= _REFER_PRICE / 2){ 515 | if(user_itr == userinfo.end()){ 516 | new_user(account, string(""), account); 517 | user_itr = userinfo.find(game_itr->gameid); 518 | } 519 | if(quantity.amount >= _REFER_PRICE){ 520 | if(user_itr != userinfo.end()){ 521 | uint64_t refer = quantity.amount / _REFER_PRICE; 522 | userinfo.modify(user_itr, account, [&](auto& u) { 523 | u.refer += refer; 524 | }); 525 | 526 | if( now() < _GAME_PRESALE_TIME){ 527 | userinfo.modify(user_itr, account, [&](auto& u) { 528 | u.quota += refer; 529 | }); 530 | } 531 | 532 | fee_userinfo.modify(fee_user_itr, account, [&](auto& u) { 533 | u.refer += refer; 534 | }); 535 | } 536 | auto refer_itr = refers.find(account); 537 | if(refer_itr == refers.end() && user_itr->refer > 0){ 538 | refer_itr = refers.emplace(account, [&](auto& r){ 539 | r.name = account; 540 | }); 541 | } 542 | auto fee_refer_itr = refers.find(FEE_ACCOUNT); 543 | if(fee_refer_itr == refers.end() && fee_user_itr->refer > 0){ 544 | fee_refer_itr = refers.emplace(account, [&](auto& r){ 545 | r.name = FEE_ACCOUNT; 546 | }); 547 | } 548 | 549 | user_table next_referinfo(_self, game_itr->next_refer); 550 | auto next_refer_itr = next_referinfo.find(game_itr->gameid); 551 | if(next_refer_itr == next_referinfo.end()){ 552 | _game.modify(game_itr, 0, [&](auto& g){ 553 | g.next_refer = account; 554 | }); 555 | } 556 | } 557 | } 558 | 559 | _game.modify(game_itr, 0, [&](auto& g) { 560 | g.insure += quantity; 561 | }); 562 | } 563 | 564 | void deposit_reward(asset quantity){ 565 | auto game_itr = _game.begin(); 566 | _game.modify(game_itr, 0, [&](auto& g) { 567 | g.reward += quantity; 568 | }); 569 | } 570 | 571 | void stake(account_name account, asset quantity){ 572 | auto game_itr = _game.begin(); 573 | if(account == game_itr->player_one){ 574 | // 当前是头号的用户可以无缝增加抵押CGT,稳住头号的位置 575 | _game.modify(game_itr, 0 , [&](auto& g){ 576 | g.staked += quantity; 577 | }); 578 | } else if(quantity > game_itr->staked){ 579 | // 取代当前的头号的位置,并且奖励周期刷新 580 | unstake(game_itr->player_one); 581 | _game.modify(game_itr, 0 , [&](auto& g){ 582 | g.staked = quantity; 583 | g.player_one = account; 584 | g.reward_time = now() + _REWARD_COOL_DOWN; 585 | }); 586 | } else { 587 | enumivo_assert(false, "需要抵押更多的CGT才能超越当前的头号"); 588 | } 589 | } 590 | 591 | void unstake(account_name account){ 592 | auto game_itr = _game.begin(); 593 | enumivo_assert(game_itr->player_one == account, "can only unstake player one's token"); 594 | asset staked = game_itr->staked; 595 | _game.modify(game_itr, 0 , [&](auto& g){ 596 | g.staked = asset(0, GAME_SYMBOL); 597 | g.player_one = FEE_ACCOUNT; 598 | }); 599 | if(staked >= asset(1000 * _UNIT, GAME_SYMBOL)){ 600 | // 争取头号的用户将有10%的抵押CGT作为手续费,解除抵押的时候收取 601 | asset fee = staked / 10; 602 | staked -= fee; 603 | _game.modify(game_itr, 0, [&](auto& g) { 604 | g.supply -= fee; 605 | g.circulation -= fee; 606 | g.burn += fee; 607 | }); 608 | 609 | action( 610 | permission_level{_self, N(active)}, 611 | GAME_TOKEN_CONTRACT, N(transfer), 612 | make_tuple(_self, BURN_ACCOUNT, fee, string("解除抵押将损失百分之十的抵押CGT"))) 613 | .send(); 614 | 615 | action( 616 | permission_level{_self, N(active)}, 617 | GAME_TOKEN_CONTRACT, N(transfer), 618 | make_tuple(_self, account, staked, string("可能有其他玩家抵押超越了您,您已经不再是头号。 网址: http://eosplayer.one"))) 619 | .send(); 620 | 621 | action( 622 | permission_level{_self, N(active)}, 623 | TOKEN_CONTRACT, N(transfer), 624 | make_tuple(_self, account, asset(1ll, CORE_SYMBOL), string("可能有其他玩家抵押超越了您,您已经不再是头号。 网址: http://eosplayer.one"))) 625 | .send(); 626 | 627 | claim_reward(game_itr->player_one); 628 | } else if(staked > asset(0, GAME_SYMBOL)){ 629 | _game.modify(game_itr, 0, [&](auto& g) { 630 | g.supply -= staked; 631 | g.circulation -= staked; 632 | g.burn += staked; 633 | }); 634 | 635 | action( 636 | permission_level{_self, N(active)}, 637 | GAME_TOKEN_CONTRACT, N(transfer), 638 | make_tuple(_self, BURN_ACCOUNT, staked, string("抵押CGT太少,将全部损失"))) 639 | .send(); 640 | } 641 | } 642 | 643 | void claim_reward(account_name account){ 644 | auto game_itr = _game.begin(); 645 | enumivo_assert(game_itr->player_one == account, "only player one can claim the reward"); 646 | asset reward = game_itr->reward; 647 | // 每一个奖励周期(24小时),头号都能够获得手续费奖池的10%,前提是发送金额大于10ENU 648 | reward.amount = reward.amount / 10; 649 | if( now() >= game_itr->reward_time && reward >= asset(10 * _UNIT, CORE_SYMBOL)){ 650 | _game.modify(game_itr, 0, [&](auto& g){ 651 | g.reward -= reward; 652 | g.reward_time = now() + _REWARD_COOL_DOWN; 653 | }); 654 | action( 655 | permission_level{_self, N(active)}, 656 | TOKEN_CONTRACT, N(transfer), 657 | make_tuple(_self, account, reward, string("头号奖励。 网址: http://eosplayer.one"))) 658 | .send(); 659 | } 660 | } 661 | 662 | void new_user(account_name account, string parent_str, account_name ram_payer){ 663 | auto game_itr = _game.begin(); 664 | user_table userinfo(_self, account); 665 | auto user_itr = userinfo.find(game_itr->gameid); 666 | if(user_itr != userinfo.end()) return; 667 | 668 | uint32_t discount = 0; 669 | auto parent = string_to_name(parent_str.c_str()); 670 | user_table parentinfo(_self, parent); 671 | auto parent_itr = parentinfo.find(game_itr->gameid); 672 | //新用户缺失推荐人的情况下将均匀分配到购买了邀请码的用户 673 | if(parent_itr == parentinfo.end() || parent_itr->refer <= 0 || account == parent){ 674 | //如果没有用户购买邀请码,新用户的上级将默认分配到FEE_ACCOUNT,否则按照推荐人队列依次分配 675 | parent = FEE_ACCOUNT; 676 | user_table next_referinfo(_self, game_itr->next_refer); 677 | auto next_refer_itr = next_referinfo.find(game_itr->gameid); 678 | if(refers.begin() != refers.end() && next_refer_itr != next_referinfo.end()){ 679 | auto refer_itr = refers.find(game_itr->next_refer); 680 | if(refer_itr != refers.end()){ 681 | user_table refer_userinfo(_self, refer_itr->name); 682 | auto refer_user_itr = refer_userinfo.find(game_itr->gameid); 683 | if(refer_user_itr != refer_userinfo.end()){ 684 | parent = refer_user_itr->name; 685 | if(refer_user_itr->refer <= 1){ 686 | refer_itr = refers.erase(refer_itr); 687 | } else { 688 | refer_itr ++; 689 | } 690 | if(refers.begin() == refers.end()){ 691 | _game.modify(game_itr, 0, [&](auto& g){ 692 | g.next_refer = BURN_ACCOUNT; 693 | }); 694 | } else if(refer_itr == refers.end()) { 695 | _game.modify(game_itr, 0, [&](auto& g){ 696 | g.next_refer = refers.begin()->name; 697 | }); 698 | } else { 699 | _game.modify(game_itr, 0, [&](auto& g){ 700 | g.next_refer = refer_itr->name; 701 | }); 702 | } 703 | } 704 | } 705 | } 706 | } else { 707 | if( now() < _GAME_PRESALE_TIME ){ 708 | parentinfo.modify(parent_itr, ram_payer, [&](auto& u){ 709 | u.quota += 1; 710 | }); 711 | } 712 | } 713 | 714 | user_table parent_info(_self, parent); 715 | parent_itr = parent_info.find(game_itr->gameid); 716 | //分配到邀请码的新用户交易手续费减少50% 717 | if(parent_itr->refer > 0){ 718 | discount = 1; 719 | parent_info.modify(parent_itr, ram_payer, [&](auto& u){ 720 | u.refer --; 721 | }); 722 | } 723 | 724 | userinfo.emplace(ram_payer, [&](auto& u) { 725 | u.gameid = game_itr->gameid; 726 | u.name = account; 727 | u.parent = parent; 728 | u.discount = discount; 729 | u.last_action = now(); 730 | }); 731 | } 732 | 733 | void collect_fee(account_name account, asset fee){ 734 | //邀请奖励累积到合约,统一赎回 735 | if (fee.amount > 0){ 736 | //邀请奖励金池与主奖金池隔离 737 | auto game_itr = _game.begin(); 738 | _game.modify(game_itr, account, [&](auto& g){ 739 | g.fee += fee; 740 | }); 741 | 742 | asset refer_fee = fee; 743 | refer_fee = fee / 2; 744 | fee -= refer_fee; 745 | 746 | user_table userinfo(_self, account); 747 | auto user_itr = userinfo.find(game_itr->gameid); 748 | if(user_itr == userinfo.end()) return; 749 | user_table parentinfo(_self, user_itr->parent); 750 | auto parent_itr = parentinfo.find(game_itr->gameid); 751 | if(parent_itr == parentinfo.end()) return; 752 | //邀请奖励回馈直接上级50% 753 | parentinfo.modify(parent_itr, account, [&](auto& u){ 754 | u.reward += fee; 755 | }); 756 | 757 | if (refer_fee.amount > 0) 758 | { 759 | user_table second_parentinfo(_self, parent_itr->parent); 760 | auto second_parent_itr = second_parentinfo.find(game_itr->gameid); 761 | if(second_parent_itr == second_parentinfo.end()) return; 762 | //邀请奖励二级回馈50% 763 | second_parentinfo.modify(second_parent_itr, account, [&](auto& u){ 764 | u.reward += refer_fee; 765 | }); 766 | } 767 | } 768 | } 769 | 770 | void claim_fee(account_name account){ 771 | auto game_itr = _game.begin(); 772 | user_table userinfo(_self, account); 773 | auto user_itr = userinfo.find(game_itr->gameid); 774 | if(user_itr == userinfo.end()) return; 775 | //邀请奖励累积到1ENU及以上才能够赎回 776 | if(user_itr->reward >= asset(_UNIT, CORE_SYMBOL)){ 777 | asset reward = user_itr->reward; 778 | userinfo.modify(user_itr, account, [&](auto& u){ 779 | u.reward = asset(0, CORE_SYMBOL); 780 | }); 781 | //邀请奖励金池与主奖金池隔离 782 | _game.modify(game_itr, account, [&](auto& g){ 783 | g.fee -= reward; 784 | }); 785 | //邀请奖励金池与主奖金池隔离 786 | enumivo_assert(game_itr->fee >= asset(0, CORE_SYMBOL), "shit happens"); 787 | action( 788 | permission_level{_self, N(active)}, 789 | TOKEN_CONTRACT, N(transfer), 790 | make_tuple(_self, user_itr->name, reward, string("获得邀请奖励。 网址: http://eosplayer.one"))) 791 | .send(); 792 | } 793 | } 794 | 795 | private: 796 | real_type _crr(asset circulation) { 797 | enumivo_assert(circulation.amount >= 0, "shit happens"); 798 | real_type A(_A); 799 | real_type B(_B); 800 | real_type L(_L); 801 | real_type D(_D); 802 | real_type ONE(1.0); 803 | real_type H(100.0); 804 | real_type UNIT(_UNIT); 805 | real_type E(2.71828182845904); 806 | 807 | real_type X(circulation.amount); 808 | X = X / UNIT; 809 | 810 | real_type R = ONE / (ONE + pow(E, (X - L) / D)) * A + B; 811 | enumivo_assert(R >= B && R <= B + A, "shit happens"); 812 | return R / H; 813 | } 814 | 815 | string name_to_string(account_name name){ 816 | static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz"; 817 | string str(13,'.'); 818 | uint64_t tmp = name; 819 | for( uint32_t i = 0; i <= 12; ++i ) { 820 | char c = charmap[tmp & (i == 0 ? 0x0f : 0x1f)]; 821 | str[12-i] = c; 822 | tmp >>= (i == 0 ? 4 : 5); 823 | } 824 | const auto last = str.find_last_not_of('.'); 825 | if (last != string::npos) 826 | str = str.substr(0, last + 1); 827 | return str; 828 | } 829 | 830 | // @abi table game i64 831 | struct game{ 832 | account_name gameid; 833 | asset reserve = asset(0, CORE_SYMBOL); 834 | asset insure = asset(0, CORE_SYMBOL); 835 | asset max_supply = asset(0, CORE_SYMBOL); 836 | asset supply = asset(0, GAME_SYMBOL); 837 | asset balance = asset(0, GAME_SYMBOL); 838 | asset circulation = asset(0, GAME_SYMBOL); 839 | asset burn = asset(0, GAME_SYMBOL); 840 | asset staked = asset(0, GAME_SYMBOL); 841 | asset fee = asset(0, CORE_SYMBOL); 842 | asset reward = asset(0, CORE_SYMBOL); 843 | account_name next_refer = FEE_ACCOUNT; 844 | account_name player_one = FEE_ACCOUNT; 845 | uint64_t start_time; 846 | uint64_t reward_time; 847 | 848 | uint64_t primary_key() const { return gameid; } 849 | ENULIB_SERIALIZE(game, (gameid)(reserve)(insure)(max_supply)(supply)(balance)(circulation)(burn)(staked)(fee)(reward)(next_refer)(player_one)(start_time)(reward_time)) 850 | }; 851 | typedef enumivo::multi_index game_table; 852 | game_table _game; 853 | 854 | // @abi table userinfo i64 855 | struct user{ 856 | account_name gameid; 857 | account_name name; 858 | account_name parent; 859 | asset reward = asset(0, CORE_SYMBOL); 860 | uint64_t last_action; 861 | uint64_t refer = 0; 862 | uint64_t quota = 0; 863 | uint32_t discount = 0; 864 | 865 | uint64_t primary_key() const { return gameid; } 866 | ENULIB_SERIALIZE(user, (gameid)(name)(parent)(reward)(last_action)(refer)(quota)(discount)) 867 | }; 868 | typedef enumivo::multi_index user_table; 869 | // user_table userinfo; 870 | 871 | // @abi table refers i64 872 | struct refer{ 873 | account_name name; 874 | uint64_t primary_key() const { return name; } 875 | ENULIB_SERIALIZE(refer, (name)) 876 | }; 877 | typedef enumivo::multi_index refer_table; 878 | refer_table refers; 879 | 880 | // @abi table invitations i64 881 | struct invitation{ 882 | account_name to; 883 | account_name from; 884 | uint64_t primary_key() const { return to; } 885 | ENULIB_SERIALIZE(invitation, (to)(from)) 886 | }; 887 | typedef enumivo::multi_index invitation_table; 888 | invitation_table invitations; 889 | }; 890 | 891 | #define ENU_ABI_EX( TYPE, MEMBERS ) \ 892 | extern "C" { \ 893 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \ 894 | auto self = receiver; \ 895 | if(action == N(onerror)) { \ 896 | /* onerror is only valid if it is for the "enumivo" code account and authorized by "enumivo"'s "active permission */ \ 897 | enumivo_assert(code == N(enumivo), "onerror action's are only valid from the \"enumivo\" system account"); \ 898 | } \ 899 | if(action == N(transfer)) { \ 900 | auto _action = N(onerror); \ 901 | if(code == TOKEN_CONTRACT) { \ 902 | _action = N(enu_token_transfer); \ 903 | } else if(code == GAME_TOKEN_CONTRACT) { \ 904 | _action = N(game_token_transfer); \ 905 | } \ 906 | if(_action == N(onerror)) { \ 907 | enumivo_assert(false, "action from this code is denied"); \ 908 | } \ 909 | TYPE thiscontract( self ); \ 910 | switch( _action ) { \ 911 | ENUMIVO_API( TYPE, MEMBERS ) \ 912 | } \ 913 | /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \ 914 | } \ 915 | } \ 916 | } \ 917 | 918 | ENU_ABI_EX(playerone, (enu_token_transfer)(game_token_transfer)) -------------------------------------------------------------------------------- /enuplayerone/playerone.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | enucli push action enu.token transfer '["testuseraaaa", "oneplayerone", "2.0000 ENU", "deposit"]' -p testuseraaaa 4 | enucli push action enu.token transfer '["testuseraaad", "oneplayerone", "2.0000 ENU", "deposit"]' -p testuseraaad 5 | 6 | for ((i=0; i<20; ++i)) 7 | do 8 | enucli push action enu.token transfer '["testuseraaaa", "oneplayerone", "100.0000 ENU", "testuseraaaa"]' -p testuseraaaa 9 | enucli push action enu.token transfer '["testuseraaab", "oneplayerone", "100.0000 ENU", "testuseraaaa"]' -p testuseraaab 10 | enucli push action enu.token transfer '["testuseraaac", "oneplayerone", "100.0000 ENU", "testuseraaab"]' -p testuseraaac 11 | enucli push action enu.token transfer '["testuseraaad", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaad 12 | enucli push action enu.token transfer '["testuseraaae", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaae 13 | enucli push action enu.token transfer '["testuseraaaf", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaaf 14 | enucli push action enu.token transfer '["testuseraaag", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaag 15 | enucli push action enu.token transfer '["testuseraaah", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaah 16 | enucli push action enu.token transfer '["testuseraaai", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaai 17 | enucli push action enu.token transfer '["testuseraaaj", "oneplayerone", "100.0000 ENU", ""]' -p testuseraaaj 18 | 19 | enucli push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaa 20 | enucli push action playeroneiss transfer '["testuseraaab", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaab 21 | enucli push action playeroneiss transfer '["testuseraaac", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaac 22 | enucli push action playeroneiss transfer '["testuseraaad", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaad 23 | enucli push action playeroneiss transfer '["testuseraaae", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaae 24 | enucli push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaf 25 | enucli push action playeroneiss transfer '["testuseraaag", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaag 26 | enucli push action playeroneiss transfer '["testuseraaah", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaah 27 | enucli push action playeroneiss transfer '["testuseraaai", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaai 28 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaj 29 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 30 | 31 | done 32 | 33 | for ((i=0; i<15; ++i)) 34 | do 35 | enucli push action enu.token transfer '["testuseraaaa", "oneplayerone", "50.0000 ENU", "testuseraaaa"]' -p testuseraaaa 36 | enucli push action enu.token transfer '["testuseraaab", "oneplayerone", "50.0000 ENU", "testuseraaaa"]' -p testuseraaab 37 | enucli push action enu.token transfer '["testuseraaac", "oneplayerone", "50.0000 ENU", "testuseraaab"]' -p testuseraaac 38 | enucli push action enu.token transfer '["testuseraaad", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaad 39 | enucli push action enu.token transfer '["testuseraaae", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaae 40 | enucli push action enu.token transfer '["testuseraaaf", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaaf 41 | enucli push action enu.token transfer '["testuseraaag", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaag 42 | enucli push action enu.token transfer '["testuseraaah", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaah 43 | enucli push action enu.token transfer '["testuseraaai", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaai 44 | enucli push action enu.token transfer '["testuseraaaj", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaaj 45 | 46 | enucli push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaa 47 | enucli push action playeroneiss transfer '["testuseraaab", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaab 48 | enucli push action playeroneiss transfer '["testuseraaac", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaac 49 | enucli push action playeroneiss transfer '["testuseraaad", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaad 50 | enucli push action playeroneiss transfer '["testuseraaae", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaae 51 | enucli push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaf 52 | enucli push action playeroneiss transfer '["testuseraaag", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaag 53 | enucli push action playeroneiss transfer '["testuseraaah", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaah 54 | enucli push action playeroneiss transfer '["testuseraaai", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaai 55 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaj 56 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 57 | done 58 | 59 | for ((i=0; i<20; ++i)) 60 | do 61 | enucli push action enu.token transfer '["testuseraaaa", "oneplayerone", "50.0000 ENU", "testuseraaaa"]' -p testuseraaaa 62 | enucli push action enu.token transfer '["testuseraaab", "oneplayerone", "50.0000 ENU", "testuseraaaa"]' -p testuseraaab 63 | enucli push action enu.token transfer '["testuseraaac", "oneplayerone", "50.0000 ENU", "testuseraaab"]' -p testuseraaac 64 | enucli push action enu.token transfer '["testuseraaad", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaad 65 | enucli push action enu.token transfer '["testuseraaae", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaae 66 | enucli push action enu.token transfer '["testuseraaaf", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaaf 67 | enucli push action enu.token transfer '["testuseraaag", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaag 68 | enucli push action enu.token transfer '["testuseraaah", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaah 69 | enucli push action enu.token transfer '["testuseraaai", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaai 70 | enucli push action enu.token transfer '["testuseraaaj", "oneplayerone", "50.0000 ENU", ""]' -p testuseraaaj 71 | 72 | enucli push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaa 73 | enucli push action playeroneiss transfer '["testuseraaab", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaab 74 | enucli push action playeroneiss transfer '["testuseraaac", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaac 75 | enucli push action playeroneiss transfer '["testuseraaad", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaad 76 | enucli push action playeroneiss transfer '["testuseraaae", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaae 77 | enucli push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaf 78 | enucli push action playeroneiss transfer '["testuseraaag", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaag 79 | enucli push action playeroneiss transfer '["testuseraaah", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaah 80 | enucli push action playeroneiss transfer '["testuseraaai", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaai 81 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaj 82 | enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 83 | done 84 | 85 | 86 | # enucli transfer enu.token playeronefee "1 ENU" "test" -p enu.token 87 | # enucli transfer playeronefee oneplayerone "0.0001 ENU" "test" -p playeronefee 88 | 89 | # enucli push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", "stake"]' -p testuseraaaa 90 | # enucli push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "stake"]' -p testuseraaaj 91 | # enucli transfer testuseraaaa oneplayerone "0.0001 ENU" "test" -p testuseraaaa 92 | # enucli transfer testuseraaai oneplayerone "0.0001 ENU" "test" -p testuseraaai 93 | 94 | # enucli push action enu.token transfer '["testuseraaaa", "oneplayerone", "0.0001 ENU", "testuseraaaj"]' -p testuseraaaa 95 | 96 | enucli get table oneplayerone testuseraaaa userinfo 97 | enucli get table oneplayerone testuseraaab userinfo 98 | enucli get table oneplayerone testuseraaac userinfo 99 | enucli get table oneplayerone testuseraaad userinfo 100 | enucli get table oneplayerone testuseraaae userinfo 101 | enucli get table oneplayerone testuseraaaf userinfo 102 | enucli get table oneplayerone testuseraaag userinfo 103 | enucli get table oneplayerone testuseraaah userinfo 104 | enucli get table oneplayerone testuseraaai userinfo 105 | enucli get table oneplayerone testuseraaaj userinfo 106 | enucli get table oneplayerone oneplayerone refers 107 | enucli get table oneplayerone oneplayerone game 108 | enucli get table oneplayerone oneplayerone invitations 109 | echo enucli get currency balance playeroneiss oneplayerone CGT 110 | enucli get currency balance playeroneiss oneplayerone CGT 111 | echo enucli get currency balance playeroneiss blackholeeos CGT 112 | enucli get currency balance playeroneiss blackholeeos CGT 113 | echo enucli get currency balance enu.token oneplayerone ENU 114 | enucli get currency balance enu.token oneplayerone ENU 115 | echo enucli get currency balance enu.token playeronefee ENU 116 | enucli get currency balance enu.token playeronefee ENU 117 | echo enucli get currency stats playeroneiss CGT 118 | enucli get currency stats playeroneiss CGT -------------------------------------------------------------------------------- /enuplayerone/playerone.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/enuplayerone/playerone.wasm -------------------------------------------------------------------------------- /enuplayerone/playerone_init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # assume you have imported the officials' keys 4 | enucli wallet import --private-key 5KaVNWNF2LtdxBT8fGUV81yXZjKiu7qdR28myrUKEXcem8gc1qy 5 | enucli wallet import --private-key 5KNGa5bkAW8sP5dqcYNHQSvAXQtsfU9yyLr87SBvE7F3RyonUZ1 6 | enucli wallet import --private-key 5JdthYKccniLB7w5VQegU4HkERpzMD9yQ1hK3AJvduZKAr9EoeT 7 | enucli wallet import --private-key 5K5rvrLPKP9tNkLngX9vJcLDYeh6nAurakb2Xwc2CpaRaAwazZ4 8 | 9 | 10 | # blackholeeos = ENU5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi=KEY:5KaVNWNF2LtdxBT8fGUV81yXZjKiu7qdR28myrUKEXcem8gc1qy 11 | enucli create account enumivo blackholeeos ENU5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi ENU5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi 12 | 13 | # playeronefee = ENU7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza=KEY:5KNGa5bkAW8sP5dqcYNHQSvAXQtsfU9yyLr87SBvE7F3RyonUZ1 14 | enucli create account enumivo playeronefee ENU7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza ENU7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza 15 | 16 | # oneplayerone = ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go=KEY:5JdthYKccniLB7w5VQegU4HkERpzMD9yQ1hK3AJvduZKAr9EoeT 17 | enucli create account enumivo oneplayerone ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go 18 | # enucli system newaccount enumivo oneplayerone ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go --stake-net "10.0000 SYS" --stake-cpu "10.0000 SYS" --buy-ram-kbytes 1000 19 | 20 | # playeroneiss = ENU8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo=KEY:5K5rvrLPKP9tNkLngX9vJcLDYeh6nAurakb2Xwc2CpaRaAwazZ4 21 | enucli create account enumivo playeroneiss ENU8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo ENU8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo 22 | # enucli system newaccount enumivo playeroneiss ENU8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo ENU8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo --stake-net "10.0000 SYS" --stake-cpu "10.0000 SYS" --buy-ram-kbytes 10000 23 | 24 | # enucli set contract oneplayerone ./build/playerone -p oneplayerone 25 | enucli set code oneplayerone ./playerone.wasm -p oneplayerone 26 | enucli set abi oneplayerone ./playerone.abi -p oneplayerone 27 | 28 | enucli set contract playeroneiss ./enu.token -p playeroneiss 29 | enucli push action playeroneiss create '[ "oneplayerone", "250000000.0000 CGT"]' -p playeroneiss 30 | 31 | enucli set account permission oneplayerone active '{"threshold": 1,"keys": [{"key": "ENU4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go","weight": 1}],"accounts": [{"permission":{"actor":"oneplayerone","permission":"enumivo.code"},"weight":1}]}' owner -p oneplayerone 32 | 33 | # follow test must throw 34 | # enucli push action playeroneiss create '[ "playeronefee", "10000000.0000 ENU"]' -p playeroneiss 35 | # enucli push action playeroneiss issue '[ "playeronefee", "100000.0000 ENU"]' -p playeronefee 36 | # enucli push action playeroneiss transfer '["playeronefee", "oneplayerone", "10.1111 ENU", "testuseraaaa"]' -p playeronefee 37 | 38 | # follow test must throw 39 | # enucli push action playeronefee create '[ "playeronefee", "10000000.0000 ENU"]' -p playeronefee 40 | # enucli push action playeronefee create '[ "playeronefee", "10000000.0000 CGT"]' -p playeronefee 41 | # enucli push action playeronefee issue '[ "playeronefee", "10000000.0000 ENU", "initial supply" ]' -p playeronefee 42 | # enucli push action playeronefee issue '[ "playeronefee", "10000000.0000 CGT", "initial supply" ]' -p playeronefee 43 | # enucli push action playeronefee transfer '["playeronefee", "oneplayerone", "10.1111 ENU", "testuseraaaa"]' -p playeronefee 44 | # enucli push action playeronefee transfer '["playeronefee", "oneplayerone", "10.1111 CGT", "testuseraaaa"]' -p playeronefee 45 | -------------------------------------------------------------------------------- /eos_init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # assume you have pre-installed eos https://github.com/EOSIO/eos 4 | # assume you have pre-installed eosio.wasmsdk https://github.com/EOSIO/eosio.wasmsdk 5 | # assume you have pre-installed eosio.contracts https://github.com/EOSIO/eosio.contracts 6 | # maybe you need change this two dir path 7 | 8 | EOS_HOME=../eos 9 | EOS_CONTRACT_HOME=../eosio.contracts 10 | 11 | cleos set contract eosio ${EOS_HOME}/build/contracts/eosio.bios -p eosio@active 12 | 13 | cleos create account eosio eosio.msig EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV 14 | cleos set contract eosio.msig ${EOS_CONTRACT_HOME}/build/eosio.msig -p eosio.msig@active 15 | 16 | cleos create account eosio eosio.system EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV 17 | cleos set contract eosio.system ${EOS_CONTRACT_HOME}/build/eosio.system -p eosio.system@active 18 | 19 | cleos create account eosio eosio.sudo EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV 20 | cleos set contract eosio.sudo ${EOS_CONTRACT_HOME}/build/eosio.sudo -p eosio.sudo@active 21 | 22 | # assume you have imported the eosio master key to have root privilege in eos 23 | # signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 24 | cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 25 | 26 | # assume you have imported the testers' keys 27 | cleos wallet import --private-key 5KKUS3oXbTQpmL1TqYm8xo8Zy9XNQ6DwwJwuUzAzo2CBRqSRweV 28 | cleos wallet import --private-key 5JVVQpGNWLz3nUcPDjeixSH6mi2pRW6da9ErLWK3RaMipWJox37 29 | cleos wallet import --private-key 5K9ZQFXzeesmjdUqPQytg1KKiDGTWSDsW5jQHqUZttVi9VLwrJX 30 | cleos wallet import --private-key 5JcxRgm2WkD5x482BG3gjE4kJde9CqMutPcq3k2UYYajuNkR5wN 31 | cleos wallet import --private-key 5JrsSNfzM5YDQmdkYfgRBQtSQ9WZccM6n7CRGrBE9g7CrG6NHhM 32 | cleos wallet import --private-key 5JYAkZt781wVvtxg3Y41hBRT2SSxEVeNTiyJKKrBXTMGCwKQJCx 33 | cleos wallet import --private-key 5JSHN5z385ZEikDzdrU1ixZp1XYoNw7m8X9s1LYaUWxt3Y3gbDG 34 | cleos wallet import --private-key 5KGx9WDVGWeXU7twpQ9dRsJUEsk4tf7b4UcLEYT8JANJyeiUsyD 35 | cleos wallet import --private-key 5KCa3Pvq5APMZYCz3qABisnDA1sUtYiKwinLWU7aHqv2kU7BQYb 36 | cleos wallet import --private-key 5KA7efGfZdFpgEX37uPiDQAarfacs5X5W6GUzk9kdQzhrSZJiW9 37 | cleos wallet import --private-key 5JTGHQaHSXz6HCqt4QCtabfptz7pCrpmMMLdZD7nbUSRtEvEcuL 38 | 39 | 40 | # eosio.token = EOS87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E=KEY:5KKUS3oXbTQpmL1TqYm8xo8Zy9XNQ6DwwJwuUzAzo2CBRqSRweV 41 | cleos create account eosio eosio.token EOS87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E EOS87infeXNHe3cRzc71MNcQESM6DFWYjMU5MvSSrji7nup4x4K2E 42 | cleos set contract eosio.token ./build/eosio.token -p eosio.token 43 | 44 | cleos push action eosio.token create '[ "eosio.token", "1000000000.0000 EOS"]' -p eosio.token 45 | cleos push action eosio.token issue '[ "eosio.token", "1000000000.0000 EOS", "initial supply" ]' -p eosio.token 46 | 47 | 48 | # testuseraaaa = EOS7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm=KEY:5JVVQpGNWLz3nUcPDjeixSH6mi2pRW6da9ErLWK3RaMipWJox37 49 | cleos create account eosio testuseraaaa EOS7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm EOS7aozLD8SsjCtxhMTfDaCh6PBrQKwJ1NvSDCtxe4SvkmzkmLudm 50 | # testuseraaab = EOS6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo=KEY:5K9ZQFXzeesmjdUqPQytg1KKiDGTWSDsW5jQHqUZttVi9VLwrJX 51 | cleos create account eosio testuseraaab EOS6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo EOS6dd5jBWi32fg12NyP8sX6fdWU58xo7dDcdPB5wxJWfBiomP3eo 52 | # testuseraaac = EOS6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW=KEY:5JcxRgm2WkD5x482BG3gjE4kJde9CqMutPcq3k2UYYajuNkR5wN 53 | cleos create account eosio testuseraaac EOS6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW EOS6Bwd1ydLTXfjHsFGFVvwkhASezVzENXNJBx5MyJXsPiEsMrWFW 54 | # testuseraaad = EOS7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU=KEY:5JrsSNfzM5YDQmdkYfgRBQtSQ9WZccM6n7CRGrBE9g7CrG6NHhM 55 | cleos create account eosio testuseraaad EOS7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU EOS7XEHhumorTShir1ks2dq6XB1RAWtKk7sSGhNzUBSJx6Xn9Q3QU 56 | # testuseraaae = EOS8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n=KEY:5JYAkZt781wVvtxg3Y41hBRT2SSxEVeNTiyJKKrBXTMGCwKQJCx 57 | cleos create account eosio testuseraaae EOS8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n EOS8j55oVcKj1cNnY9UFo1f4hDnt9XrKTpNasmJQAgZBPdR55JZ3n 58 | # testuseraaaf = EOS696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a=KEY:5JSHN5z385ZEikDzdrU1ixZp1XYoNw7m8X9s1LYaUWxt3Y3gbDG 59 | cleos create account eosio testuseraaaf EOS696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a EOS696FezUddFSEBzqTq93eiCJPZthdQhxz6gkBxKgx51D9ZrFR6a 60 | # testuseraaag = EOS5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg=KEY:5KGx9WDVGWeXU7twpQ9dRsJUEsk4tf7b4UcLEYT8JANJyeiUsyD 61 | cleos create account eosio testuseraaag EOS5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg EOS5hvH6RTo4KcRfdBGnhm42pLBWCPTm7rivknWCXUFaBkQBa8ZQg 62 | # testuseraaah = EOS5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH=KEY:5KCa3Pvq5APMZYCz3qABisnDA1sUtYiKwinLWU7aHqv2kU7BQYb 63 | cleos create account eosio testuseraaah EOS5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH EOS5wsrYqCrXDZrdWShEgeF43riaf9NEdJTdfoB1RhEBspDFzG3ZH 64 | # testuseraaai = EOS6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ=KEY:5KA7efGfZdFpgEX37uPiDQAarfacs5X5W6GUzk9kdQzhrSZJiW9 65 | cleos create account eosio testuseraaai EOS6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ EOS6tVvMqXjHKCV37kPdJeDu49UmBgQKPv12ndZToPBL5N4iMxjVQ 66 | # testuseraaaj = EOS5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd=KEY:5JTGHQaHSXz6HCqt4QCtabfptz7pCrpmMMLdZD7nbUSRtEvEcuL 67 | cleos create account eosio testuseraaaj EOS5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd EOS5JCzKF1NHnY2Z4EwxG3EjFvoKCukjjzmB1moAU61eqRucGdeqd 68 | 69 | cleos transfer eosio.token testuseraaaa "100000 EOS" "test" -p eosio.token 70 | cleos transfer eosio.token testuseraaab "100000 EOS" "test" -p eosio.token 71 | cleos transfer eosio.token testuseraaac "100000 EOS" "test" -p eosio.token 72 | cleos transfer eosio.token testuseraaad "100000 EOS" "test" -p eosio.token 73 | cleos transfer eosio.token testuseraaae "100000 EOS" "test" -p eosio.token 74 | cleos transfer eosio.token testuseraaaf "100000 EOS" "test" -p eosio.token 75 | cleos transfer eosio.token testuseraaag "100000 EOS" "test" -p eosio.token 76 | cleos transfer eosio.token testuseraaah "100000 EOS" "test" -p eosio.token 77 | cleos transfer eosio.token testuseraaai "100000 EOS" "test" -p eosio.token 78 | cleos transfer eosio.token testuseraaaj "100000 EOS" "test" -p eosio.token 79 | 80 | -------------------------------------------------------------------------------- /eosio.token/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TARGET "eosio.token") 2 | add_executable(${TARGET}.wasm ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.cpp) 3 | 4 | target_include_directories(${TARGET}.wasm 5 | PUBLIC 6 | ${CMAKE_CURRENT_SOURCE_DIR}/include) 7 | 8 | set_target_properties(${TARGET}.wasm 9 | PROPERTIES 10 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") 11 | 12 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/${TARGET}.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) -------------------------------------------------------------------------------- /eosio.token/abi/eosio.token.abi: -------------------------------------------------------------------------------- 1 | { 2 | "version": "eosio::abi/1.0", 3 | "types": [{ 4 | "new_type_name": "account_name", 5 | "type": "name" 6 | }], 7 | "structs": [{ 8 | "name": "transfer", 9 | "base": "", 10 | "fields": [ 11 | {"name":"from", "type":"account_name"}, 12 | {"name":"to", "type":"account_name"}, 13 | {"name":"quantity", "type":"asset"}, 14 | {"name":"memo", "type":"string"} 15 | ] 16 | },{ 17 | "name": "create", 18 | "base": "", 19 | "fields": [ 20 | {"name":"issuer", "type":"account_name"}, 21 | {"name":"maximum_supply", "type":"asset"} 22 | ] 23 | },{ 24 | "name": "issue", 25 | "base": "", 26 | "fields": [ 27 | {"name":"to", "type":"account_name"}, 28 | {"name":"quantity", "type":"asset"}, 29 | {"name":"memo", "type":"string"} 30 | ] 31 | },{ 32 | "name": "account", 33 | "base": "", 34 | "fields": [ 35 | {"name":"balance", "type":"asset"} 36 | ] 37 | },{ 38 | "name": "currency_stats", 39 | "base": "", 40 | "fields": [ 41 | {"name":"supply", "type":"asset"}, 42 | {"name":"max_supply", "type":"asset"}, 43 | {"name":"issuer", "type":"account_name"} 44 | ] 45 | } 46 | ], 47 | "actions": [{ 48 | "name": "transfer", 49 | "type": "transfer", 50 | "ricardian_contract": "" 51 | },{ 52 | "name": "issue", 53 | "type": "issue", 54 | "ricardian_contract": "" 55 | }, { 56 | "name": "create", 57 | "type": "create", 58 | "ricardian_contract": "" 59 | } 60 | 61 | ], 62 | "tables": [{ 63 | "name": "accounts", 64 | "type": "account", 65 | "index_type": "i64", 66 | "key_names" : ["currency"], 67 | "key_types" : ["uint64"] 68 | },{ 69 | "name": "stat", 70 | "type": "currency_stats", 71 | "index_type": "i64", 72 | "key_names" : ["currency"], 73 | "key_types" : ["uint64"] 74 | } 75 | ], 76 | "ricardian_clauses": [], 77 | "abi_extensions": [] 78 | } 79 | -------------------------------------------------------------------------------- /eosio.token/eosio.token.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @copyright defined in eos/LICENSE.txt 4 | */ 5 | 6 | #include "eosio.token.hpp" 7 | 8 | namespace eosio { 9 | 10 | void token::create( account_name issuer, 11 | asset maximum_supply ) 12 | { 13 | require_auth( _self ); 14 | 15 | auto sym = maximum_supply.symbol; 16 | eosio_assert( sym.is_valid(), "invalid symbol name" ); 17 | eosio_assert( maximum_supply.is_valid(), "invalid supply"); 18 | eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); 19 | 20 | stats statstable( _self, sym.name() ); 21 | auto existing = statstable.find( sym.name() ); 22 | eosio_assert( existing == statstable.end(), "token with symbol already exists" ); 23 | 24 | statstable.emplace( _self, [&]( auto& s ) { 25 | s.supply.symbol = maximum_supply.symbol; 26 | s.max_supply = maximum_supply; 27 | s.issuer = issuer; 28 | }); 29 | } 30 | 31 | 32 | void token::issue( account_name to, asset quantity, string memo ) 33 | { 34 | auto sym = quantity.symbol; 35 | eosio_assert( sym.is_valid(), "invalid symbol name" ); 36 | eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 37 | 38 | auto sym_name = sym.name(); 39 | stats statstable( _self, sym_name ); 40 | auto existing = statstable.find( sym_name ); 41 | eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); 42 | const auto& st = *existing; 43 | 44 | require_auth( st.issuer ); 45 | eosio_assert( quantity.is_valid(), "invalid quantity" ); 46 | eosio_assert( quantity.amount > 0, "must issue positive quantity" ); 47 | 48 | eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 49 | eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); 50 | 51 | statstable.modify( st, 0, [&]( auto& s ) { 52 | s.supply += quantity; 53 | }); 54 | 55 | add_balance( st.issuer, quantity, st.issuer ); 56 | 57 | if( to != st.issuer ) { 58 | SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); 59 | } 60 | } 61 | 62 | void token::transfer( account_name from, 63 | account_name to, 64 | asset quantity, 65 | string memo ) 66 | { 67 | eosio_assert( from != to, "cannot transfer to self" ); 68 | require_auth( from ); 69 | eosio_assert( is_account( to ), "to account does not exist"); 70 | auto sym = quantity.symbol.name(); 71 | stats statstable( _self, sym ); 72 | const auto& st = statstable.get( sym ); 73 | 74 | require_recipient( from ); 75 | require_recipient( to ); 76 | 77 | eosio_assert( quantity.is_valid(), "invalid quantity" ); 78 | eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); 79 | eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 80 | eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 81 | 82 | 83 | sub_balance( from, quantity ); 84 | add_balance( to, quantity, from ); 85 | } 86 | 87 | void token::sub_balance( account_name owner, asset value ) { 88 | accounts from_acnts( _self, owner ); 89 | 90 | const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); 91 | eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); 92 | 93 | 94 | if( from.balance.amount == value.amount ) { 95 | from_acnts.erase( from ); 96 | } else { 97 | from_acnts.modify( from, owner, [&]( auto& a ) { 98 | a.balance -= value; 99 | }); 100 | } 101 | } 102 | 103 | void token::add_balance( account_name owner, asset value, account_name ram_payer ) 104 | { 105 | accounts to_acnts( _self, owner ); 106 | auto to = to_acnts.find( value.symbol.name() ); 107 | if( to == to_acnts.end() ) { 108 | to_acnts.emplace( ram_payer, [&]( auto& a ){ 109 | a.balance = value; 110 | }); 111 | } else { 112 | to_acnts.modify( to, 0, [&]( auto& a ) { 113 | a.balance += value; 114 | }); 115 | } 116 | } 117 | 118 | } /// namespace eosio 119 | 120 | EOSIO_ABI( eosio::token, (create)(issue)(transfer) ) 121 | -------------------------------------------------------------------------------- /img/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/img/logo.jpg -------------------------------------------------------------------------------- /img/logo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/img/logo1.jpg -------------------------------------------------------------------------------- /img/logo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/img/logo2.jpg -------------------------------------------------------------------------------- /img/price.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/img/price.png -------------------------------------------------------------------------------- /info.md: -------------------------------------------------------------------------------- 1 | ![](https://raw.githubusercontent.com/dabdevelop/playerone/master/img/logo2.jpg) 2 | 3 | # 头号玩家项目介绍 4 | 5 | 《头号玩家》是一个基于锚定母币稳定增值的货币发行模型,也是一款由社区自发构建“去中心化自治银行”的资金盘游戏,通过游戏的博弈来测试和验证“去中心化自治银行”的可行性。 6 | 7 | ## 头号玩家 相关信息 8 | 9 | * 官网: [http://eosplayer.one](http://eosplayer.one) 10 | * 合约账号: [oneplayerone](https://eosflare.io/account/oneplayerone) 11 | * 权限移交: [oneplayerone](https://eospark.com/MainNet/Account/oneplayerone) 12 | * 源代码: [github](https://github.com/DAB-Foundation/playerone) 13 | * 邮件: [support@dab.vc](support@dab.vc) 14 | 15 | 通过团队协商,头号玩家决定采用多签的方式保留更新合约的权力。 16 | 多签的持有人包括:知名开发者和社群群主。 17 | 18 | * ITE开发者账号: **itedeveloper@acive** 19 | * 岛娘: **minakokojima@active** 20 | * TP钱包: **itokenpocket@active** 21 | * 社区群主只言片语: **wanshijian55@active** 22 | * PlayerOne开发者账号: **playeronefee@active** 23 | 24 | 25 | 合约源码经过长时间开源,并且邀请了众多知名开发者进行安全审计,安全性可靠性高。 26 | 27 | ## 项目定位 28 | 29 | 《头号玩家》是一个共同持股的“去中心化自治银行”。拥有CGT的玩家都是此次试验中“去中心化自治银行”的股东。在《头号玩家》中,玩家可以用EOS买卖等值的CGT代币,CGT代币价格随着发行量的增加而缓慢增长,其价格完全由参与玩家形成的市场调节:参与的玩家越多、应用场景越丰富、币的稀释度和流动性越高,CGT的价值也越高,从而实现资本增值。 30 | 31 | 《头号玩家》将与股东一起,与其他游戏平台合作,将众多股东形成的用户流量进行接入,实现流量的变现。 32 | 33 | 目前已经拥有的合作伙伴包括: 34 | 35 | 柚资银行,通过《头号玩家》进行CPU租赁可以享受8折以下优惠。 36 | 37 | TP钱包,方便广大用户直接使用《头号玩家》的平台。 38 | 39 | 并且与EOS生态中的其他平台正在对接。 40 | 41 | CGT的使用包括但是不限于:用户间直接支付,平台利润分红,接入其他游戏平台,上线去中心化交易所。 42 | 43 | 这是一个可投资、可投机的项目。 44 | 45 | ## CGT的发行规则 46 | ### 发行时间 47 | 北京时间 2018-08-31 20:08:08 48 | 49 | 时间戳: 1535717288 50 | 51 | ### 初始价格和总量 52 | CGT初始价格是:0.01EOS 53 | 54 | 发行量: **500万** 55 | 56 | 价格的变化幅度最高能够增长20倍。 57 | 58 | 当发行500万CGT时价格趋于稳定,如下图所示: 59 |  60 | ![](https://raw.githubusercontent.com/dabdevelop/playerone/master/img/price.png) 61 | 62 | ### CGT的特点 63 | 64 | CGT无私募,不众筹,不空投。 65 | 66 | CGT采用类bancor算法发行和定价。总量恒定,价格由市场供需调节。持有者越多时,价值越大。抛售者越多时,价格降低。 67 | 68 | 和任何ICO发币不一样的是,团队成员不持有任何原始股。 69 | 70 | CGT能够随时买卖,既可以长期持有,也可以短期套利。 71 | 72 | 不同于经典Bancor算法的是,CGT设置了退出机制,与卖出形成一个互相制约的博弈机制,保证玩家在大量抛售时CGT不会归零。 73 | 74 | ### 限购策略 75 | 76 | 一方面为了抵制机器人,另一方面为了更多玩家参与,稀释股权。前10分钟为预售阶段,买入限时限量。限时:每个用户会有平均30秒的冷却时间,前两次买入间隔越短,下次买入冷却时间越长,t = 225 / (dt + 1),t为冷却时间,dt是冷却后等待的时间(根据公式,等待15秒最佳,但是玩家可以灵活地选择进入方式)。预售结束后冷却时间降为1秒。限量:预售阶段用户每次免费额度10EOS,购买邀请码可以获得等量额外额度。 77 | 78 | ### 买卖方式 79 | 买入:将EOS转账到合约账号 80 | 81 | 卖出:将CGT转账到合约账号 82 | 83 | 另外可以备注填写推荐人的账号名,通过推荐人注册可以减免一部分手续费。 84 | 85 | ### 手续费 86 | 87 | 通过邀请码注册的用户买卖手续费为1.9%,没有通过邀请码注册的用户为2.8%。手续费分配:0.5%给上级,0.5%给上级的上级,剩下的部分一半进入头玩奖池,一半累积到Pool。除了手续费之外,没有其他任何抽水。手续费的存在是为了防止机器人褥羊毛,也是为了维持头号玩家更好的运行。 88 | 89 | ## 两级邀请奖励 90 | 91 | 任何一位玩家买卖CGT,都会向上2级贡献总资金1%的利润,按照50%,50%的比例划分给2个上级。通过购买邀请码,成为其他玩家的上级,每个人都有机会站在金字塔顶端。 92 | 93 | 拥有邀请码的用户还可以主动邀请新用户,成为他的上级,享受其0.5%的交易手续费。预售前每次成功的邀请还能够获得1EOS额外额度(适合各游戏社区群主),大于200EOS后不能通过邀请继续增加。 94 | 95 | 邀请码需要单独购买,价格为一个邀请码1EOS,能够为一名玩家降低手续费,并成为他的上级。 96 | 97 | ## 头号玩家的福利 98 | 99 | 另外,增加了头号玩家的竞争,玩家通过抵押CGT,可以竞争头号玩家的头衔。头号玩家拥有特殊分红,每24小时,头号玩家可以获得头号奖池的10%,单次分红需要超过10EOS。但是每次竞争将会有10%的CGT作为损耗,在解除抵押时扣除。 100 | 101 | ## CGT的价值在哪里: 102 | 103 | 《头号玩家》原创作品曾在星云开发者激励计划中先后斩获周冠、月冠,是第一款将“去中心化自治银行”构建理论游戏化的Dapp。《头号玩家》原创作品出现的时间在EOS RAM炒作之前,更在F3D和其他基于Bancor模型的资金盘游戏前。可以说《头号玩家》是这一系列游戏的引领者。此次实现EOS版本的DAB,基本保持了原有的经济模型,虽然很多玩法相比于后起之秀有些单一,但是希望玩家们多多支持。团队不是为了盈利,而是为了DAB的信仰。 104 | 105 | 2017年下半年,以太坊1.53亿美元的超大ICO——Bancor,创下了新的行业记录。 106 | 107 | Bancor是一个去中心化交易系统的模型,也是团队的灵感来源,正是深入研究了Bancor模型,团队产生了开发一款“去中心化自治银行”(DAB)构建理论的想法;在设计上,DAB模型不仅可以实现Bancor模型的全部内容,还比Bancor模型更具有鲁棒性和稳定性。 108 | 109 | 游戏本质是尝试在区块链上建立一个“去中心化自治银行”,而这个“银行”不赚用户的钱。 110 | 111 | 在现实生活中,银行用户的存款和贷款都是不透明的,而且中间存在高额的利率差,中心化的银行操纵着利率; 112 | 113 | 既然有了区块链,我们为什么不能把这个过程透明化呢?同时,利用分布式账本技术的去中心化,实现银行自适性的货币发行和信用授予,使得整个存借过程更快捷、更安全。 114 | 115 | CGT不是空气币,《头号玩家》这个项目的经济模型也不是一个封闭的模型,而是一个完全开放,充满想象力的模型,是从0到1是的突破,而从1到10就相对容易了 116 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "requires": true, 3 | "lockfileVersion": 1, 4 | "dependencies": { 5 | "base-x": { 6 | "version": "3.0.4", 7 | "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", 8 | "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", 9 | "requires": { 10 | "safe-buffer": "^5.0.1" 11 | } 12 | }, 13 | "bigi": { 14 | "version": "1.4.2", 15 | "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", 16 | "integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=" 17 | }, 18 | "browserify-aes": { 19 | "version": "1.2.0", 20 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 21 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 22 | "requires": { 23 | "buffer-xor": "^1.0.3", 24 | "cipher-base": "^1.0.0", 25 | "create-hash": "^1.1.0", 26 | "evp_bytestokey": "^1.0.3", 27 | "inherits": "^2.0.1", 28 | "safe-buffer": "^5.0.1" 29 | } 30 | }, 31 | "bs58": { 32 | "version": "4.0.1", 33 | "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", 34 | "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", 35 | "requires": { 36 | "base-x": "^3.0.2" 37 | } 38 | }, 39 | "buffer-xor": { 40 | "version": "1.0.3", 41 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 42 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" 43 | }, 44 | "bytebuffer": { 45 | "version": "5.0.1", 46 | "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", 47 | "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", 48 | "requires": { 49 | "long": "~3" 50 | } 51 | }, 52 | "cipher-base": { 53 | "version": "1.0.4", 54 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 55 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 56 | "requires": { 57 | "inherits": "^2.0.1", 58 | "safe-buffer": "^5.0.1" 59 | } 60 | }, 61 | "create-hash": { 62 | "version": "1.2.0", 63 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 64 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 65 | "requires": { 66 | "cipher-base": "^1.0.1", 67 | "inherits": "^2.0.1", 68 | "md5.js": "^1.3.4", 69 | "ripemd160": "^2.0.1", 70 | "sha.js": "^2.4.0" 71 | } 72 | }, 73 | "create-hmac": { 74 | "version": "1.1.7", 75 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 76 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 77 | "requires": { 78 | "cipher-base": "^1.0.3", 79 | "create-hash": "^1.1.0", 80 | "inherits": "^2.0.1", 81 | "ripemd160": "^2.0.0", 82 | "safe-buffer": "^5.0.1", 83 | "sha.js": "^2.4.8" 84 | } 85 | }, 86 | "ecurve": { 87 | "version": "1.0.6", 88 | "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz", 89 | "integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==", 90 | "requires": { 91 | "bigi": "^1.1.0", 92 | "safe-buffer": "^5.0.1" 93 | } 94 | }, 95 | "eosjs-ecc": { 96 | "version": "4.0.2", 97 | "resolved": "https://registry.npmjs.org/eosjs-ecc/-/eosjs-ecc-4.0.2.tgz", 98 | "integrity": "sha512-ATfS036BEEyJYS98/of1/KnC0TLzFUEWDWthtIxD+5SuYD7FrPpJTS9qdfAWvzlxV3zzVxTh3eQryqS637qjAw==", 99 | "requires": { 100 | "bigi": "^1.4.2", 101 | "browserify-aes": "^1.0.6", 102 | "bs58": "^4.0.1", 103 | "bytebuffer": "^5.0.1", 104 | "create-hash": "^1.1.3", 105 | "create-hmac": "^1.1.6", 106 | "ecurve": "^1.0.5", 107 | "randombytes": "^2.0.5" 108 | } 109 | }, 110 | "evp_bytestokey": { 111 | "version": "1.0.3", 112 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 113 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 114 | "requires": { 115 | "md5.js": "^1.3.4", 116 | "safe-buffer": "^5.1.1" 117 | } 118 | }, 119 | "hash-base": { 120 | "version": "3.0.4", 121 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", 122 | "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", 123 | "requires": { 124 | "inherits": "^2.0.1", 125 | "safe-buffer": "^5.0.1" 126 | } 127 | }, 128 | "inherits": { 129 | "version": "2.0.3", 130 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 131 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 132 | }, 133 | "long": { 134 | "version": "3.2.0", 135 | "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", 136 | "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" 137 | }, 138 | "md5.js": { 139 | "version": "1.3.4", 140 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", 141 | "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", 142 | "requires": { 143 | "hash-base": "^3.0.0", 144 | "inherits": "^2.0.1" 145 | } 146 | }, 147 | "randombytes": { 148 | "version": "2.0.6", 149 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", 150 | "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", 151 | "requires": { 152 | "safe-buffer": "^5.1.0" 153 | } 154 | }, 155 | "ripemd160": { 156 | "version": "2.0.2", 157 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 158 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 159 | "requires": { 160 | "hash-base": "^3.0.0", 161 | "inherits": "^2.0.1" 162 | } 163 | }, 164 | "safe-buffer": { 165 | "version": "5.1.2", 166 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 167 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 168 | }, 169 | "sha.js": { 170 | "version": "2.4.11", 171 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 172 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 173 | "requires": { 174 | "inherits": "^2.0.1", 175 | "safe-buffer": "^5.0.1" 176 | } 177 | } 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "eosjs-ecc": "^4.0.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /playerone.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "2.0000 EOS", "deposit"]' -p testuseraaaa 4 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "2.0000 EOS", "deposit"]' -p testuseraaad 5 | 6 | for ((i=0; i<20; ++i)) 7 | do 8 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "100.0000 EOS", "testuseraaaa"]' -p testuseraaaa 9 | cleos push action eosio.token transfer '["testuseraaab", "oneplayerone", "100.0000 EOS", "testuseraaaa"]' -p testuseraaab 10 | cleos push action eosio.token transfer '["testuseraaac", "oneplayerone", "100.0000 EOS", "testuseraaab"]' -p testuseraaac 11 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaad 12 | cleos push action eosio.token transfer '["testuseraaae", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaae 13 | cleos push action eosio.token transfer '["testuseraaaf", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaaf 14 | cleos push action eosio.token transfer '["testuseraaag", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaag 15 | cleos push action eosio.token transfer '["testuseraaah", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaah 16 | cleos push action eosio.token transfer '["testuseraaai", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaai 17 | cleos push action eosio.token transfer '["testuseraaaj", "oneplayerone", "100.0000 EOS", ""]' -p testuseraaaj 18 | 19 | cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaa 20 | cleos push action playeroneiss transfer '["testuseraaab", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaab 21 | cleos push action playeroneiss transfer '["testuseraaac", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaac 22 | cleos push action playeroneiss transfer '["testuseraaad", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaad 23 | cleos push action playeroneiss transfer '["testuseraaae", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaae 24 | cleos push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaf 25 | cleos push action playeroneiss transfer '["testuseraaag", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaag 26 | cleos push action playeroneiss transfer '["testuseraaah", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaah 27 | cleos push action playeroneiss transfer '["testuseraaai", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaai 28 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaj 29 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 30 | 31 | done 32 | 33 | for ((i=0; i<15; ++i)) 34 | do 35 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "50.0000 EOS", "testuseraaaa"]' -p testuseraaaa 36 | cleos push action eosio.token transfer '["testuseraaab", "oneplayerone", "50.0000 EOS", "testuseraaaa"]' -p testuseraaab 37 | cleos push action eosio.token transfer '["testuseraaac", "oneplayerone", "50.0000 EOS", "testuseraaab"]' -p testuseraaac 38 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaad 39 | cleos push action eosio.token transfer '["testuseraaae", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaae 40 | cleos push action eosio.token transfer '["testuseraaaf", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaaf 41 | cleos push action eosio.token transfer '["testuseraaag", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaag 42 | cleos push action eosio.token transfer '["testuseraaah", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaah 43 | cleos push action eosio.token transfer '["testuseraaai", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaai 44 | cleos push action eosio.token transfer '["testuseraaaj", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaaj 45 | 46 | cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaa 47 | cleos push action playeroneiss transfer '["testuseraaab", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaab 48 | cleos push action playeroneiss transfer '["testuseraaac", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaac 49 | cleos push action playeroneiss transfer '["testuseraaad", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaad 50 | cleos push action playeroneiss transfer '["testuseraaae", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaae 51 | cleos push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaf 52 | cleos push action playeroneiss transfer '["testuseraaag", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaag 53 | cleos push action playeroneiss transfer '["testuseraaah", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaah 54 | cleos push action playeroneiss transfer '["testuseraaai", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaai 55 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "500.0000 CGT", ""]' -p testuseraaaj 56 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 57 | done 58 | 59 | for ((i=0; i<20; ++i)) 60 | do 61 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "50.0000 EOS", "testuseraaaa"]' -p testuseraaaa 62 | cleos push action eosio.token transfer '["testuseraaab", "oneplayerone", "50.0000 EOS", "testuseraaaa"]' -p testuseraaab 63 | cleos push action eosio.token transfer '["testuseraaac", "oneplayerone", "50.0000 EOS", "testuseraaab"]' -p testuseraaac 64 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaad 65 | cleos push action eosio.token transfer '["testuseraaae", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaae 66 | cleos push action eosio.token transfer '["testuseraaaf", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaaf 67 | cleos push action eosio.token transfer '["testuseraaag", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaag 68 | cleos push action eosio.token transfer '["testuseraaah", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaah 69 | cleos push action eosio.token transfer '["testuseraaai", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaai 70 | cleos push action eosio.token transfer '["testuseraaaj", "oneplayerone", "50.0000 EOS", ""]' -p testuseraaaj 71 | 72 | cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaa 73 | cleos push action playeroneiss transfer '["testuseraaab", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaab 74 | cleos push action playeroneiss transfer '["testuseraaac", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaac 75 | cleos push action playeroneiss transfer '["testuseraaad", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaad 76 | cleos push action playeroneiss transfer '["testuseraaae", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaae 77 | cleos push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaf 78 | cleos push action playeroneiss transfer '["testuseraaag", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaag 79 | cleos push action playeroneiss transfer '["testuseraaah", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaah 80 | cleos push action playeroneiss transfer '["testuseraaai", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaai 81 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "100.0000 CGT", ""]' -p testuseraaaj 82 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "burn"]' -p testuseraaaj 83 | done 84 | 85 | 86 | # cleos transfer eosio.token playeronefee "1 EOS" "test" -p eosio.token 87 | # cleos transfer playeronefee oneplayerone "0.0001 EOS" "test" -p playeronefee 88 | 89 | # cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "100.0000 CGT", "stake"]' -p testuseraaaa 90 | # cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "1000.0000 CGT", "stake"]' -p testuseraaaj 91 | # cleos transfer testuseraaaa oneplayerone "0.0001 EOS" "test" -p testuseraaaa 92 | # cleos transfer testuseraaai oneplayerone "0.0001 EOS" "test" -p testuseraaai 93 | 94 | # cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaaj"]' -p testuseraaaa 95 | 96 | cleos get table oneplayerone testuseraaaa userinfo 97 | cleos get table oneplayerone testuseraaab userinfo 98 | cleos get table oneplayerone testuseraaac userinfo 99 | cleos get table oneplayerone testuseraaad userinfo 100 | cleos get table oneplayerone testuseraaae userinfo 101 | cleos get table oneplayerone testuseraaaf userinfo 102 | cleos get table oneplayerone testuseraaag userinfo 103 | cleos get table oneplayerone testuseraaah userinfo 104 | cleos get table oneplayerone testuseraaai userinfo 105 | cleos get table oneplayerone testuseraaaj userinfo 106 | cleos get table oneplayerone oneplayerone refers 107 | cleos get table oneplayerone oneplayerone game 108 | cleos get table oneplayerone oneplayerone invitations 109 | echo cleos get currency balance playeroneiss oneplayerone CGT 110 | cleos get currency balance playeroneiss oneplayerone CGT 111 | echo cleos get currency balance playeroneiss blackholeeos CGT 112 | cleos get currency balance playeroneiss blackholeeos CGT 113 | echo cleos get currency balance eosio.token oneplayerone EOS 114 | cleos get currency balance eosio.token oneplayerone EOS 115 | echo cleos get currency balance eosio.token playeronefee EOS 116 | cleos get currency balance eosio.token playeronefee EOS 117 | echo cleos get currency stats playeroneiss CGT 118 | cleos get currency stats playeroneiss CGT -------------------------------------------------------------------------------- /playerone/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(TARGET "playerone") 2 | add_executable(${TARGET}.wasm ${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.cpp) 3 | 4 | target_include_directories(${TARGET}.wasm 5 | PUBLIC 6 | ${CMAKE_CURRENT_SOURCE_DIR}/include) 7 | 8 | set_target_properties(${TARGET}.wasm 9 | PROPERTIES 10 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") 11 | 12 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/${TARGET}.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) -------------------------------------------------------------------------------- /playerone/README.md: -------------------------------------------------------------------------------- 1 | ### CLAUSE NAME: Warranty 2 | WARRANTY. The invoker of the contract action shall uphold its Obligations under this Contract in a timely and workmanlike manner, using knowledge and recommendations for performing the services which meet generally acceptable standards set forth by EOS.IO Blockchain Block Producers. 3 | 4 | ### CLAUSE NAME: Default 5 | DEFAULT. The occurrence of any of the following shall constitute a material default under this Contract: 6 | 7 | ### CLAUSE NAME: Remedies 8 | REMEDIES. In addition to any and all other rights a party may have available according to law, if a party defaults by failing to substantially perform any provision, term or condition of this Contract, the other party may terminate the Contract by providing written notice to the defaulting party. This notice shall describe with sufficient detail the nature of the default. The party receiving such notice shall promptly be removed from being a Block Producer and this Contract shall be automatically terminated. 9 | 10 | ### CLAUSE NAME: Force Majeure 11 | FORCE MAJEURE. If performance of this Contract or any obligation under this Contract is prevented, restricted, or interfered with by causes beyond either party's reasonable control ("Force Majeure"), and if the party unable to carry out its obligations gives the other party prompt written notice of such event, then the obligations of the party invoking this provision shall be suspended to the extent necessary by such event. The term Force Majeure shall include, without limitation, acts of God, fire, explosion, vandalism, storm or other similar occurrence, orders or acts of military or civil authority, or by national emergencies, insurrections, riots, or wars, or strikes, lock-outs, work stoppages, or supplier failures. The excused party shall use reasonable efforts under the circumstances to avoid or remove such causes of non-performance and shall proceed to perform with reasonable dispatch whenever such causes are removed or ceased. An act or omission shall be deemed within the reasonable control of a party if committed, omitted, or caused by such party, or its employees, officers, agents, or affiliates. 12 | 13 | ### CLAUSE NAME: Dispute Resolution 14 | DISPUTE RESOLUTION. Any controversies or disputes arising out of or relating to this Contract will be resolved by binding arbitration under the default rules set forth by the EOS.IO Blockchain. The arbitrator's award will be final, and judgment may be entered upon it by any court having proper jurisdiction. 15 | 16 | ### CLAUSE NAME: Entire Agreement 17 | ENTIRE AGREEMENT. This Contract contains the entire agreement of the parties, and there are no other promises or conditions in any other agreement whether oral or written concerning the subject matter of this Contract. This Contract supersedes any prior written or oral agreements between the parties. 18 | 19 | ### CLAUSE NAME: Severability 20 | SEVERABILITY. If any provision of this Contract will be held to be invalid or unenforceable for any reason, the remaining provisions will continue to be valid and enforceable. If a court finds that any provision of this Contract is invalid or unenforceable, but that by limiting such provision it would become valid and enforceable, then such provision will be deemed to be written, construed, and enforced as so limited. 21 | 22 | ### CLAUSE NAME: Amendment 23 | AMENDMENT. This Contract may be modified or amended in writing by mutual agreement between the parties, if the writing is signed by the party obligated under the amendment. 24 | 25 | ### CLAUSE NAME: Governing Law 26 | GOVERNING LAW. This Contract shall be construed in accordance with the Maxims of Equity. 27 | 28 | ### CLAUSE NAME: Notice 29 | NOTICE. Any notice or communication required or permitted under this Contract shall be sufficiently given if delivered to a verifiable email address or to such other email address as one party may have publicly furnished in writing, or published on a broadcast contract provided by this blockchain for purposes of providing notices of this type. 30 | ### CLAUSE NAME: Waiver of Contractual Right 31 | WAIVER OF CONTRACTUAL RIGHT. The failure of either party to enforce any provision of this Contract shall not be construed as a waiver or limitation of that party's right to subsequently enforce and compel strict compliance with every provision of this Contract. 32 | 33 | ### CLAUSE NAME: Arbitrator's Fees to Prevailing Party 34 | ARBITRATOR'S FEES TO PREVAILING PARTY. In any action arising hereunder or any separate action pertaining to the validity of this Agreement, both sides shall pay half the initial cost of arbitration, and the prevailing party shall be awarded reasonable arbitrator's fees and costs. 35 | 36 | ### CLAUSE NAME: Construction and Interpretation 37 | CONSTRUCTION AND INTERPRETATION. The rule requiring construction or interpretation against the drafter is waived. The document shall be deemed as if it were drafted by both parties in a mutual effort. 38 | 39 | ### CLAUSE NAME: In Witness Whereof 40 | IN WITNESS WHEREOF, the parties hereto have caused this Agreement to be executed by themselves or their duly authorized representatives as of the date of execution, and authorized as proven by the cryptographic signature on the transaction that invokes this contract. 41 | -------------------------------------------------------------------------------- /playerone/abi/playerone.abi: -------------------------------------------------------------------------------- 1 | { 2 | "____comment": "This file was generated by eosio-abigen. DO NOT EDIT - 2018-08-18T20:58:10", 3 | "version": "eosio::abi/1.0", 4 | "types": [], 5 | "structs": [{ 6 | "name": "game", 7 | "base": "", 8 | "fields": [{ 9 | "name": "gameid", 10 | "type": "name" 11 | },{ 12 | "name": "reserve", 13 | "type": "asset" 14 | },{ 15 | "name": "insure", 16 | "type": "asset" 17 | },{ 18 | "name": "max_supply", 19 | "type": "asset" 20 | },{ 21 | "name": "supply", 22 | "type": "asset" 23 | },{ 24 | "name": "balance", 25 | "type": "asset" 26 | },{ 27 | "name": "circulation", 28 | "type": "asset" 29 | },{ 30 | "name": "burn", 31 | "type": "asset" 32 | },{ 33 | "name": "staked", 34 | "type": "asset" 35 | },{ 36 | "name": "fee", 37 | "type": "asset" 38 | },{ 39 | "name": "reward", 40 | "type": "asset" 41 | },{ 42 | "name": "next_refer", 43 | "type": "name" 44 | },{ 45 | "name": "player_one", 46 | "type": "name" 47 | },{ 48 | "name": "start_time", 49 | "type": "uint64" 50 | },{ 51 | "name": "reward_time", 52 | "type": "uint64" 53 | } 54 | ] 55 | },{ 56 | "name": "user", 57 | "base": "", 58 | "fields": [{ 59 | "name": "gameid", 60 | "type": "name" 61 | },{ 62 | "name": "name", 63 | "type": "name" 64 | },{ 65 | "name": "parent", 66 | "type": "name" 67 | },{ 68 | "name": "reward", 69 | "type": "asset" 70 | },{ 71 | "name": "last_action", 72 | "type": "uint64" 73 | },{ 74 | "name": "refer", 75 | "type": "uint64" 76 | },{ 77 | "name": "quota", 78 | "type": "uint64" 79 | },{ 80 | "name": "discount", 81 | "type": "uint32" 82 | } 83 | ] 84 | },{ 85 | "name": "refer", 86 | "base": "", 87 | "fields": [{ 88 | "name": "name", 89 | "type": "name" 90 | } 91 | ] 92 | },{ 93 | "name": "invitation", 94 | "base": "", 95 | "fields": [{ 96 | "name": "to", 97 | "type": "name" 98 | },{ 99 | "name": "from", 100 | "type": "name" 101 | } 102 | ] 103 | } 104 | ], 105 | "actions": [], 106 | "tables": [{ 107 | "name": "game", 108 | "index_type": "i64", 109 | "key_names": [ 110 | "gameid" 111 | ], 112 | "key_types": [ 113 | "name" 114 | ], 115 | "type": "game" 116 | },{ 117 | "name": "userinfo", 118 | "index_type": "i64", 119 | "key_names": [ 120 | "gameid" 121 | ], 122 | "key_types": [ 123 | "name" 124 | ], 125 | "type": "user" 126 | },{ 127 | "name": "refers", 128 | "index_type": "i64", 129 | "key_names": [ 130 | "name" 131 | ], 132 | "key_types": [ 133 | "name" 134 | ], 135 | "type": "refer" 136 | },{ 137 | "name": "invitations", 138 | "index_type": "i64", 139 | "key_names": [ 140 | "to" 141 | ], 142 | "key_types": [ 143 | "name" 144 | ], 145 | "type": "invitation" 146 | } 147 | ], 148 | "ricardian_clauses": [], 149 | "error_messages": [], 150 | "abi_extensions": [] 151 | } -------------------------------------------------------------------------------- /playerone/include/eosio.token/eosio.token.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @copyright defined in eos/LICENSE.txt 4 | */ 5 | 6 | #include "eosio.token.hpp" 7 | 8 | namespace eosio { 9 | 10 | void token::create( account_name issuer, 11 | asset maximum_supply ) 12 | { 13 | require_auth( _self ); 14 | 15 | auto sym = maximum_supply.symbol; 16 | eosio_assert( sym.is_valid(), "invalid symbol name" ); 17 | eosio_assert( maximum_supply.is_valid(), "invalid supply"); 18 | eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); 19 | 20 | stats statstable( _self, sym.name() ); 21 | auto existing = statstable.find( sym.name() ); 22 | eosio_assert( existing == statstable.end(), "token with symbol already exists" ); 23 | 24 | statstable.emplace( _self, [&]( auto& s ) { 25 | s.supply.symbol = maximum_supply.symbol; 26 | s.max_supply = maximum_supply; 27 | s.issuer = issuer; 28 | }); 29 | } 30 | 31 | 32 | void token::issue( account_name to, asset quantity, string memo ) 33 | { 34 | auto sym = quantity.symbol; 35 | eosio_assert( sym.is_valid(), "invalid symbol name" ); 36 | eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 37 | 38 | auto sym_name = sym.name(); 39 | stats statstable( _self, sym_name ); 40 | auto existing = statstable.find( sym_name ); 41 | eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); 42 | const auto& st = *existing; 43 | 44 | require_auth( st.issuer ); 45 | eosio_assert( quantity.is_valid(), "invalid quantity" ); 46 | eosio_assert( quantity.amount > 0, "must issue positive quantity" ); 47 | 48 | eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 49 | eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); 50 | 51 | statstable.modify( st, 0, [&]( auto& s ) { 52 | s.supply += quantity; 53 | }); 54 | 55 | add_balance( st.issuer, quantity, st.issuer ); 56 | 57 | if( to != st.issuer ) { 58 | SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); 59 | } 60 | } 61 | 62 | void token::transfer( account_name from, 63 | account_name to, 64 | asset quantity, 65 | string memo ) 66 | { 67 | eosio_assert( from != to, "cannot transfer to self" ); 68 | require_auth( from ); 69 | eosio_assert( is_account( to ), "to account does not exist"); 70 | auto sym = quantity.symbol.name(); 71 | stats statstable( _self, sym ); 72 | const auto& st = statstable.get( sym ); 73 | 74 | require_recipient( from ); 75 | require_recipient( to ); 76 | 77 | eosio_assert( quantity.is_valid(), "invalid quantity" ); 78 | eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); 79 | eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); 80 | eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); 81 | 82 | 83 | sub_balance( from, quantity ); 84 | add_balance( to, quantity, from ); 85 | } 86 | 87 | void token::sub_balance( account_name owner, asset value ) { 88 | accounts from_acnts( _self, owner ); 89 | 90 | const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); 91 | eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); 92 | 93 | 94 | if( from.balance.amount == value.amount ) { 95 | from_acnts.erase( from ); 96 | } else { 97 | from_acnts.modify( from, owner, [&]( auto& a ) { 98 | a.balance -= value; 99 | }); 100 | } 101 | } 102 | 103 | void token::add_balance( account_name owner, asset value, account_name ram_payer ) 104 | { 105 | accounts to_acnts( _self, owner ); 106 | auto to = to_acnts.find( value.symbol.name() ); 107 | if( to == to_acnts.end() ) { 108 | to_acnts.emplace( ram_payer, [&]( auto& a ){ 109 | a.balance = value; 110 | }); 111 | } else { 112 | to_acnts.modify( to, 0, [&]( auto& a ) { 113 | a.balance += value; 114 | }); 115 | } 116 | } 117 | 118 | } /// namespace eosio 119 | 120 | EOSIO_ABI( eosio::token, (create)(issue)(transfer) ) 121 | -------------------------------------------------------------------------------- /playerone/include/eosio.token/eosio.token.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * @copyright defined in eos/LICENSE.txt 4 | */ 5 | #pragma once 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace eosiosystem { 13 | class system_contract; 14 | } 15 | 16 | namespace eosio { 17 | 18 | using std::string; 19 | 20 | class token : public contract { 21 | public: 22 | token( account_name self ):contract(self){} 23 | 24 | void create( account_name issuer, 25 | asset maximum_supply); 26 | 27 | void issue( account_name to, asset quantity, string memo ); 28 | 29 | void transfer( account_name from, 30 | account_name to, 31 | asset quantity, 32 | string memo ); 33 | 34 | 35 | inline asset get_supply( symbol_name sym )const; 36 | 37 | inline asset get_balance( account_name owner, symbol_name sym )const; 38 | 39 | private: 40 | struct account { 41 | asset balance; 42 | 43 | uint64_t primary_key()const { return balance.symbol.name(); } 44 | }; 45 | 46 | struct currency_stats { 47 | asset supply; 48 | asset max_supply; 49 | account_name issuer; 50 | 51 | uint64_t primary_key()const { return supply.symbol.name(); } 52 | }; 53 | 54 | typedef eosio::multi_index accounts; 55 | typedef eosio::multi_index stats; 56 | 57 | void sub_balance( account_name owner, asset value ); 58 | void add_balance( account_name owner, asset value, account_name ram_payer ); 59 | 60 | public: 61 | struct transfer_args { 62 | account_name from; 63 | account_name to; 64 | asset quantity; 65 | string memo; 66 | }; 67 | }; 68 | 69 | asset token::get_supply( symbol_name sym )const 70 | { 71 | stats statstable( _self, sym ); 72 | const auto& st = statstable.get( sym ); 73 | return st.supply; 74 | } 75 | 76 | asset token::get_balance( account_name owner, symbol_name sym )const 77 | { 78 | accounts accountstable( _self, owner ); 79 | const auto& ac = accountstable.get( sym ); 80 | return ac.balance; 81 | } 82 | 83 | } /// namespace eosio 84 | -------------------------------------------------------------------------------- /playerone/playerone.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Orange on 2018/8/8. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #define GAME_SYMBOL S(4, CGT) 10 | #define TOKEN_CONTRACT N(eosio.token) 11 | #define GAME_TOKEN_CONTRACT N(playeroneiss) 12 | #define BURN_ACCOUNT N(blackholeeos) 13 | #define FEE_ACCOUNT N(playeronefee) 14 | #define CPUBANK_ACCOUNT N(eosiocpubank) 15 | 16 | typedef double real_type; 17 | 18 | using namespace eosio; 19 | using namespace std; 20 | 21 | class playerone: public contract { 22 | public: 23 | const int64_t _B = 5ll; 24 | const int64_t _A = 100ll - _B * 2; 25 | const int64_t _L = 2500000ll; 26 | const int64_t _D = _L / 4; 27 | const int64_t _INITIAL_PRICE = 100ll; 28 | const int64_t _MAX_SUPPLY_TIMES = 10ll; 29 | const int64_t _GAME_INIT_TIME = 1535717288ll; // 2018/8/31 20:8:8 30 | const int64_t _GAME_PRESALE_TIME = _GAME_INIT_TIME + 10 * 60ll; 31 | const int64_t _ACTION_COOL_DOWN = 1ll; 32 | const int64_t _REWARD_COOL_DOWN = 24 * 60 * 60ll; 33 | const int64_t _UNIT = 10000ll; 34 | const int64_t _MAX_IN_PRESALE = 10 * _UNIT; 35 | const int64_t _REFER_PRICE = _UNIT; 36 | 37 | playerone(account_name self) 38 | : contract(self), 39 | _game(_self, _self), 40 | refers(_self, _self), 41 | invitations(_self, _self) 42 | { 43 | // Create a new game if not exists 44 | auto game_itr = _game.begin(); 45 | if (game_itr == _game.end()) 46 | { 47 | game_itr = _game.emplace(_self, [&](auto& g){ 48 | g.gameid = _self; 49 | g.max_supply = asset(_L * _MAX_SUPPLY_TIMES * _UNIT, GAME_SYMBOL); 50 | g.start_time = _GAME_INIT_TIME; 51 | g.reward_time = _GAME_PRESALE_TIME + _REWARD_COOL_DOWN; 52 | }); 53 | } 54 | user_table userinfo(_self, FEE_ACCOUNT); 55 | auto user_itr = userinfo.find(game_itr->gameid); 56 | if(user_itr == userinfo.end()){ 57 | user_itr = userinfo.emplace(_self, [&](auto& u){ 58 | u.gameid = game_itr->gameid; 59 | u.name = FEE_ACCOUNT; 60 | u.parent = FEE_ACCOUNT; 61 | u.refer = 100; 62 | u.discount = 1; 63 | }); 64 | } 65 | 66 | auto refer_itr = refers.find(FEE_ACCOUNT); 67 | if(refer_itr == refers.end() && user_itr->refer > 0){ 68 | refer_itr = refers.emplace(_self, [&](auto& r){ 69 | r.name = FEE_ACCOUNT; 70 | }); 71 | } 72 | }; 73 | 74 | void eosio_token_transfer(account_name from, account_name to, asset quantity, string memo){ 75 | require_auth(from); 76 | if (from == _self || to != _self) { 77 | return; 78 | } 79 | eosio_assert(quantity.is_valid(), "invalid token transfer"); 80 | eosio_assert(quantity.symbol == CORE_SYMBOL, "unexpected asset symbol input"); 81 | 82 | transfer(from, to, quantity, memo); 83 | }; 84 | 85 | void game_token_transfer(account_name from, account_name to, asset quantity, string memo){ 86 | require_auth(from); 87 | if (from == _self || to != _self) { 88 | return; 89 | } 90 | eosio_assert(quantity.is_valid(), "invalid token transfer"); 91 | eosio_assert(quantity.symbol == GAME_SYMBOL, "unexpected asset symbol input"); 92 | 93 | transfer(from, to, quantity, memo); 94 | }; 95 | 96 | void transfer(account_name from, account_name to, asset quantity, string memo){ 97 | require_auth(from); 98 | if (from == _self || to != _self) { 99 | return; 100 | } 101 | eosio_assert(quantity.is_valid(), "invalid token transfer"); 102 | 103 | auto game_itr = _game.begin(); 104 | 105 | if(quantity.symbol == CORE_SYMBOL){ 106 | if(quantity.amount == 1ll){ 107 | if(memo.size() <= 0 || memo.size() > 12){ 108 | // 用户通过向合约转账0.0001EOS取回推荐人奖金 109 | claim_fee(from); 110 | } else { 111 | // 预售前可以通过发送邀请获得免费的预售额度。发送邀请的方式为:向合约转账0.0001EOS并且备注未注册的EOS账号,将成为他的上级(需要消耗少量RAM),每个邀请增加1EOS预售额度(邀请码会减少一个) 112 | string from_str = name_to_string(from); 113 | account_name to_user = string_to_name(memo.c_str()); 114 | auto invitation_itr = invitations.find(to_user); 115 | user_table to_userinfo(_self, to_user); 116 | auto to_user_itr = to_userinfo.find(game_itr->gameid); 117 | user_table from_userinfo(_self, from); 118 | auto from_user_itr = from_userinfo.find(game_itr->gameid); 119 | if(from_user_itr != from_userinfo.end() && invitation_itr == invitations.end() && to_user_itr == to_userinfo.end()){ 120 | action( 121 | permission_level{_self, N(active)}, 122 | TOKEN_CONTRACT, N(transfer), 123 | make_tuple(_self, to_user, quantity, from_str + "邀请您参与头号玩家,通过邀请码注册有机会减少一半的手续费。网址: http://eosplayer.one/#/?ref=" + from_str)) 124 | .send(); 125 | invitation_itr = invitations.emplace(_self, [&](auto& i){ 126 | i.to = to_user; 127 | i.from = from; 128 | }); 129 | if(from_user_itr->refer > 0){ 130 | from_userinfo.modify(from_user_itr, _self, [&](auto& u){ 131 | u.refer --; 132 | }); 133 | to_user_itr = to_userinfo.emplace(_self, [&](auto& u){ 134 | u.gameid = game_itr->gameid; 135 | u.name = to_user; 136 | u.parent = from; 137 | u.discount = 1; 138 | }); 139 | if(from_user_itr->quota < 200 && now() < _GAME_INIT_TIME ){ 140 | from_userinfo.modify(from_user_itr, _self, [&](auto& u){ 141 | u.quota += 1; 142 | }); 143 | } 144 | } 145 | } 146 | } 147 | } else if(quantity.amount == 2ll){ 148 | // 头号通过向合约转账0.0002EOS获得头号奖金 149 | // 奖励冷却时间是24小时,每次获得头号奖金池的10%,单次奖金得超过10EOS 150 | // 如果头号位置更替,奖励冷却时间将重置 151 | claim_reward(from); 152 | } else if(quantity.amount == 3ll){ 153 | // 头号通过向合约转账0.0003EOS解除抵押,将消耗抵押CGT的10% 154 | unstake(from); 155 | } else if(memo == "deposit"){ 156 | // 通过向合约转账备注deposit存入EOS,用于购买邀请码,预售结束前获得等量预售额外额度,以及之后生态接入 157 | // 存入的EOS将分红给所有流通CGT 158 | // 购买邀请码将有机会获得新用户交易手续费的分红 159 | deposit(from, quantity); 160 | } else if(memo == "reward"){ 161 | // 通过向合约转账备注reward存入头号奖励 162 | // 存入的EOS将鼓励玩家竞选头号 163 | deposit_reward(quantity); 164 | } else if(memo == "1d" || memo == "4d" || memo == "7d") { 165 | // 通过向合约转账0.01 - 1 EOS并且备注1d/4d/7d为自己租赁CPU 166 | eosio_assert(quantity.amount >= 100ll && quantity.amount <= 1 * _UNIT, "租用CPU的EOS区间是 0.01 - 1 EOS"); 167 | action( 168 | permission_level{_self, N(active)}, 169 | TOKEN_CONTRACT, N(transfer), 170 | make_tuple(_self, CPUBANK_ACCOUNT, quantity, memo + " " + name_to_string(from))) 171 | .send(); 172 | } else { 173 | eosio_assert( now() >= _GAME_INIT_TIME, "游戏开始时间是2018/8/31 20:8:8"); 174 | if( now() < _GAME_PRESALE_TIME ){ 175 | user_table userinfo(_self, from); 176 | auto user_itr = userinfo.find(game_itr->gameid); 177 | // 预售结束前可以通过存入EOS获得等量的预售额度,存入的EOS对全部流通CGT分红,不可退回。相当于两倍的价格参与预售 178 | // 预售中每次买入会有平均30秒的冷却时间,连续两次买入间隔越短,下一次买入冷却时间越长,t = 225 / (dt + 1),t为冷却时间,dt是冷却后等待的时间。预售结束之后冷却时间降为1秒。 179 | if(user_itr == userinfo.end() || quantity.amount > user_itr->quota * _UNIT + _MAX_IN_PRESALE || quantity.amount <= _MAX_IN_PRESALE ){ 180 | eosio_assert( quantity.amount >= _UNIT && quantity.amount <= _MAX_IN_PRESALE, "预售额外份额不足,请单次购买 1 - 10 EOS"); 181 | } else { 182 | // 超出10EOS的部分将从预售额度里面扣除 183 | asset quota = quantity; 184 | quota -= asset(_MAX_IN_PRESALE, CORE_SYMBOL); 185 | eosio_assert( user_itr->quota * _UNIT >= quota.amount, "预售额外份额不足,请单次购买 1 - 10 EOS"); 186 | userinfo.modify(user_itr, _self, [&](auto& u){ 187 | u.quota -= quota.amount / _UNIT; 188 | }); 189 | } 190 | } 191 | buy(from, quantity, memo); 192 | } 193 | } else if(quantity.symbol == GAME_SYMBOL) { 194 | eosio_assert( now() >= _GAME_PRESALE_TIME, "预售阶段不能够销毁、抵押、出售CGT"); 195 | if(memo == "burn"){ 196 | burn(from, quantity); 197 | } else if(memo == "stake"){ 198 | // 通过向合约转账足够的CGT并且备注stake竞争头号 199 | stake(from, quantity); 200 | } else { 201 | sell(from, quantity, memo); 202 | } 203 | } else { 204 | eosio_assert(false, "不要转入其他代币资产"); 205 | } 206 | }; 207 | 208 | void buy(account_name account, asset quantity, string memo){ 209 | eosio_assert(quantity.amount >= _UNIT && quantity.amount <= 100 * _UNIT, "买入CGT区间为 1 - 100 EOS"); 210 | 211 | asset exchange_unit = asset(20 * _UNIT, CORE_SYMBOL); 212 | int64_t times = (quantity / exchange_unit) + 1; 213 | asset deposited_eos = asset(0, CORE_SYMBOL); 214 | asset insured_eos = asset(0, CORE_SYMBOL); 215 | asset exchanged_eos = asset(0, CORE_SYMBOL); 216 | asset issued_eos = asset(0, CORE_SYMBOL); 217 | auto game_itr = _game.begin(); 218 | user_table userinfo(_self, account); 219 | auto user_itr = userinfo.find(game_itr->gameid); 220 | if(user_itr == userinfo.end()){ 221 | new_user(account, memo, _self); 222 | user_itr = userinfo.find(game_itr->gameid); 223 | } else { 224 | uint64_t now_action = now(); 225 | eosio_assert( now_action >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 226 | if( now_action < _GAME_PRESALE_TIME){ 227 | now_action += 225ll / (now_action - user_itr->last_action + 1); 228 | } 229 | userinfo.modify(user_itr, _self, [&](auto& u) { 230 | u.last_action = now_action; 231 | }); 232 | } 233 | 234 | asset fee = quantity; 235 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (first round up) 236 | 237 | asset quant_after_fee = quantity; 238 | quant_after_fee -= fee; 239 | 240 | collect_fee(account, fee); 241 | 242 | fee.amount = quant_after_fee.amount; 243 | if(user_itr->discount == 0){ 244 | fee.amount = (fee.amount + 49) / 50; /// 2% fee (second round up) 245 | } else { 246 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (discount half of the fee with a refer) 247 | } 248 | 249 | asset action_total_fee = fee; 250 | quant_after_fee -= fee; 251 | 252 | asset remain_eos = quant_after_fee; 253 | asset transfer_token = asset(0, GAME_SYMBOL); 254 | asset issue_token = asset(0, GAME_SYMBOL); 255 | asset reserve_balance = game_itr->reserve; 256 | asset token_supply = game_itr->supply; 257 | asset token_balance = game_itr->balance; 258 | asset circulation = token_supply - token_balance; 259 | real_type crr; 260 | real_type token_price; 261 | for(int64_t i = 0; i < times; i++){ 262 | if(remain_eos <= asset(0, CORE_SYMBOL)){ 263 | break; 264 | } 265 | if(exchange_unit > remain_eos){ 266 | exchange_unit = remain_eos; 267 | } 268 | if(circulation > asset(100000 * _UNIT, GAME_SYMBOL) && token_balance > asset(0, GAME_SYMBOL)){ 269 | crr = _crr(circulation); 270 | token_price = real_type(reserve_balance.amount) / (real_type(circulation.amount) * crr); 271 | asset token_per_exchange = asset(real_type(exchange_unit.amount) / token_price, GAME_SYMBOL); 272 | crr = _crr(circulation + token_per_exchange); 273 | token_price = real_type((reserve_balance + exchange_unit).amount) / (real_type(circulation.amount) * crr); 274 | token_per_exchange = asset(real_type(exchange_unit.amount) / token_price, GAME_SYMBOL); 275 | if(token_balance >= token_per_exchange){ 276 | circulation += token_per_exchange; 277 | token_balance -= token_per_exchange; 278 | transfer_token += token_per_exchange; 279 | deposited_eos += exchange_unit; 280 | remain_eos -= exchange_unit; 281 | exchanged_eos += exchange_unit; 282 | reserve_balance += exchange_unit; 283 | } else { 284 | token_per_exchange = token_balance; 285 | crr = _crr(circulation + token_per_exchange); 286 | token_price = real_type((reserve_balance + exchange_unit).amount) / (real_type(circulation.amount) * crr); 287 | circulation += token_per_exchange; 288 | token_balance -= token_per_exchange; 289 | transfer_token += token_per_exchange; 290 | asset to_deposit_eos = asset(token_price * real_type(token_per_exchange.amount), CORE_SYMBOL); 291 | deposited_eos += to_deposit_eos; 292 | remain_eos -= to_deposit_eos; 293 | exchanged_eos += to_deposit_eos; 294 | reserve_balance += to_deposit_eos; 295 | } 296 | eosio_assert(token_price >= real_type(0.0), "invalid token price"); 297 | } else { 298 | crr = _crr(circulation); 299 | asset to_issue_eos = asset(real_type(exchange_unit.amount) * crr, exchange_unit.symbol); 300 | real_type INITIAL_PRICE(_INITIAL_PRICE); 301 | real_type UNIT(_UNIT); 302 | INITIAL_PRICE = INITIAL_PRICE / UNIT; 303 | asset token_per_issue = asset(real_type(to_issue_eos.amount) / INITIAL_PRICE, GAME_SYMBOL); 304 | circulation += token_per_issue; 305 | issue_token += token_per_issue; 306 | deposited_eos += to_issue_eos; 307 | insured_eos += exchange_unit - to_issue_eos; 308 | remain_eos -= exchange_unit; 309 | issued_eos += exchange_unit; 310 | reserve_balance += to_issue_eos; 311 | } 312 | } 313 | 314 | asset refund_eos = quant_after_fee - deposited_eos - insured_eos; 315 | 316 | eosio_assert(transfer_token <= game_itr->balance, "insufficient token balance"); 317 | eosio_assert(refund_eos == remain_eos && refund_eos >= asset(0, CORE_SYMBOL) && refund_eos <= quant_after_fee, "invalid eos refund"); 318 | eosio_assert(deposited_eos >= asset(0, CORE_SYMBOL) && insured_eos >= asset(0, CORE_SYMBOL), "eos deposit or insure must be positive"); 319 | eosio_assert(transfer_token >= asset(0, GAME_SYMBOL) && issue_token >= asset(0, GAME_SYMBOL), "transfer and issue token should not be negetive"); 320 | eosio_assert(exchanged_eos + issued_eos == deposited_eos + insured_eos && quant_after_fee - remain_eos == deposited_eos + insured_eos, "eos not equal"); 321 | eosio_assert(transfer_token + issue_token >= asset(_UNIT, GAME_SYMBOL) && transfer_token + issue_token <= asset(10000 * _UNIT, GAME_SYMBOL), "transfer and issue token must in range 1 - 10000"); 322 | 323 | _game.modify(game_itr, _self, [&](auto& g) { 324 | g.reserve += deposited_eos; 325 | g.insure += insured_eos + fee / 2; 326 | g.reward += action_total_fee - fee / 2; 327 | g.supply += issue_token; 328 | g.balance = token_balance; 329 | g.circulation = circulation; 330 | }); 331 | 332 | if(refund_eos > asset(0, CORE_SYMBOL)){ 333 | _game.modify(game_itr, _self, [&](auto& g){ 334 | g.fee += refund_eos; 335 | }); 336 | userinfo.modify(user_itr, _self, [&](auto& u){ 337 | u.reward += refund_eos; 338 | }); 339 | } 340 | 341 | if(transfer_token > asset(0, GAME_SYMBOL)){ 342 | action( 343 | permission_level{_self, N(active)}, 344 | GAME_TOKEN_CONTRACT, N(transfer), 345 | make_tuple(_self, account, transfer_token, string("购买CGT,感谢您支持头号玩家。 网址: http://eosplayer.one"))) 346 | .send(); 347 | } 348 | 349 | if(issue_token > asset(0, GAME_SYMBOL)){ 350 | action( 351 | permission_level{_self, N(active)}, 352 | GAME_TOKEN_CONTRACT, N(issue), 353 | make_tuple(account, issue_token, string("发行新CGT,感谢您支持头号玩家。 网址: http://eosplayer.one"))) 354 | .send(); 355 | } 356 | } 357 | 358 | void sell(account_name account, asset quantity, string memo){ 359 | eosio_assert(quantity.amount >= _UNIT && quantity.amount <= 10000 * _UNIT, "卖出CGT区间为 1 - 10000 CGT"); 360 | asset exchange_unit = asset(2000 * _UNIT, GAME_SYMBOL); 361 | asset remain_asset = quantity; 362 | int64_t times = (quantity / exchange_unit) + 1; 363 | asset transfer_eos = asset(0, CORE_SYMBOL); 364 | auto game_itr = _game.begin(); 365 | asset reserve_balance = game_itr->reserve; 366 | asset token_supply = game_itr->supply; 367 | asset token_balance = game_itr->balance; 368 | asset circulation = token_supply - token_balance; 369 | real_type crr; 370 | real_type token_price; 371 | 372 | for(int64_t i = 0; i < times; i++){ 373 | if(remain_asset <= asset(0, GAME_SYMBOL)){ 374 | break; 375 | } 376 | if(exchange_unit > remain_asset){ 377 | exchange_unit = remain_asset; 378 | } 379 | crr = _crr(circulation); 380 | token_price = real_type(reserve_balance.amount) / (real_type(circulation.amount) * crr); 381 | asset eos_per_exchange = asset(real_type(exchange_unit.amount) * token_price, CORE_SYMBOL); 382 | reserve_balance -= eos_per_exchange; 383 | if(reserve_balance < asset(0, CORE_SYMBOL)){ 384 | eosio_assert(false, "insufficient reserve eos"); 385 | } 386 | token_price = reserve_balance.amount / (circulation.amount * crr); 387 | eos_per_exchange = asset(real_type(exchange_unit.amount) * token_price, CORE_SYMBOL); 388 | transfer_eos += eos_per_exchange; 389 | circulation -= exchange_unit; 390 | remain_asset -= exchange_unit; 391 | token_balance += exchange_unit; 392 | 393 | eosio_assert(token_price >= real_type(0.0), "invalid token price"); 394 | } 395 | 396 | eosio_assert(transfer_eos <= asset(100 * _UNIT, CORE_SYMBOL) && transfer_eos >= asset(_UNIT, CORE_SYMBOL), "卖出CGT区间为 1 - 100 EOS"); 397 | eosio_assert(remain_asset >= asset(0, GAME_SYMBOL) && quantity >= remain_asset, "remain asset is invalid"); 398 | eosio_assert(quantity - remain_asset == token_balance - game_itr->balance, "exchange asset is not equal"); 399 | eosio_assert(game_itr->reserve >= transfer_eos, "insufficient reserve eos"); 400 | 401 | user_table userinfo(_self, account); 402 | auto user_itr = userinfo.find(game_itr->gameid); 403 | if(user_itr == userinfo.end()){ 404 | new_user(account, memo, _self); 405 | user_itr = userinfo.find(game_itr->gameid); 406 | } else { 407 | eosio_assert( now() >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 408 | userinfo.modify(user_itr, _self, [&](auto& u) { 409 | u.last_action = now(); 410 | }); 411 | } 412 | 413 | asset fee = transfer_eos; 414 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (first round up) 415 | asset quant_after_fee = transfer_eos; 416 | quant_after_fee -= fee; 417 | 418 | _game.modify(game_itr, _self, [&](auto& g) { 419 | g.reserve -= transfer_eos; 420 | g.balance = token_balance; 421 | g.circulation = circulation; 422 | }); 423 | 424 | collect_fee(account, fee); 425 | 426 | fee.amount = quant_after_fee.amount; 427 | if(user_itr->discount == 0){ 428 | fee.amount = (fee.amount + 49) / 50; /// 2% fee (second round up) 429 | } else { 430 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (discount half of the fee with a refer) 431 | } 432 | 433 | asset action_total_fee = fee; 434 | quant_after_fee -= fee; 435 | 436 | _game.modify(game_itr, _self, [&](auto& g) { 437 | g.insure += fee / 2; 438 | g.reward += action_total_fee - fee / 2; 439 | }); 440 | 441 | if(remain_asset > asset(0, GAME_SYMBOL)){ 442 | action( 443 | permission_level{_self, N(active)}, 444 | GAME_TOKEN_CONTRACT, N(transfer), 445 | make_tuple(_self, account, remain_asset, string("退回多余的CGT。 网址: http://eosplayer.one"))) 446 | .send(); 447 | } 448 | 449 | if(quant_after_fee > asset(0, CORE_SYMBOL)){ 450 | action( 451 | permission_level{_self, N(active)}, 452 | TOKEN_CONTRACT, N(transfer), 453 | make_tuple(_self, account, quant_after_fee, string("卖出CGT获得EOS。 网址: http://eosplayer.one"))) 454 | .send(); 455 | } 456 | } 457 | 458 | void burn(account_name account, asset quantity){ 459 | eosio_assert(quantity.amount >= _UNIT && quantity.amount <= 10000 * _UNIT, "销毁CGT的区间为 1 - 10000 CGT"); 460 | 461 | auto game_itr = _game.begin(); 462 | asset insure_balance = game_itr->insure; 463 | asset token_supply = game_itr->supply; 464 | asset token_balance = game_itr->balance; 465 | asset circulation = token_supply - token_balance; 466 | real_type token_price = real_type(insure_balance.amount) / real_type(circulation.amount); 467 | asset transfer_eos = asset(token_price * real_type(quantity.amount), CORE_SYMBOL); 468 | 469 | eosio_assert(transfer_eos <= asset(100 * _UNIT, CORE_SYMBOL) && transfer_eos >= asset(_UNIT, CORE_SYMBOL), "销毁CGT的区间为 1 - 100 EOS"); 470 | eosio_assert(insure_balance >= transfer_eos, "insufficient insure eos"); 471 | 472 | user_table userinfo(_self, account); 473 | auto user_itr = userinfo.find(game_itr->gameid); 474 | if(user_itr == userinfo.end()){ 475 | new_user(account, string(""), _self); 476 | user_itr = userinfo.find(game_itr->gameid); 477 | } else { 478 | eosio_assert( now() >= user_itr->last_action + _ACTION_COOL_DOWN, "操作太频繁,需要时间冷却"); 479 | userinfo.modify(user_itr, _self, [&](auto& u) { 480 | u.last_action = now(); 481 | }); 482 | } 483 | 484 | asset fee = transfer_eos; 485 | fee.amount = (fee.amount + 99) / 100; /// 1% fee (round up) 486 | asset quant_after_fee = transfer_eos; 487 | quant_after_fee -= fee; 488 | 489 | collect_fee(account, fee); 490 | 491 | _game.modify(game_itr, _self, [&](auto& g) { 492 | g.insure -= transfer_eos; 493 | g.supply -= quantity; 494 | g.circulation -= quantity; 495 | g.burn += quantity; 496 | }); 497 | 498 | if(quantity > asset(0, GAME_SYMBOL)){ 499 | action( 500 | permission_level{_self, N(active)}, 501 | GAME_TOKEN_CONTRACT, N(transfer), 502 | make_tuple(_self, BURN_ACCOUNT, quantity, string("销毁CGT到黑洞账号"))) 503 | .send(); 504 | } 505 | 506 | if(quant_after_fee > asset(0, CORE_SYMBOL)){ 507 | action( 508 | permission_level{_self, N(active)}, 509 | TOKEN_CONTRACT, N(transfer), 510 | make_tuple(_self, account, quant_after_fee, string("销毁CGT获得EOS。 网址: http://eosplayer.one"))) 511 | .send(); 512 | } 513 | } 514 | 515 | void deposit(account_name account, asset quantity){ 516 | auto game_itr = _game.begin(); 517 | user_table userinfo(_self, account); 518 | auto user_itr = userinfo.find(game_itr->gameid); 519 | user_table fee_userinfo(_self, FEE_ACCOUNT); 520 | auto fee_user_itr = fee_userinfo.find(game_itr->gameid); 521 | if(quantity.amount >= _REFER_PRICE / 2){ 522 | if(user_itr == userinfo.end()){ 523 | new_user(account, string(""), _self); 524 | user_itr = userinfo.find(game_itr->gameid); 525 | } 526 | if(quantity.amount >= _REFER_PRICE){ 527 | if(user_itr != userinfo.end()){ 528 | uint64_t refer = quantity.amount / _REFER_PRICE; 529 | userinfo.modify(user_itr, _self, [&](auto& u) { 530 | u.refer += refer; 531 | }); 532 | 533 | if( now() < _GAME_PRESALE_TIME){ 534 | userinfo.modify(user_itr, _self, [&](auto& u) { 535 | u.quota += refer; 536 | }); 537 | } 538 | 539 | fee_userinfo.modify(fee_user_itr, _self, [&](auto& u) { 540 | u.refer += refer; 541 | }); 542 | } 543 | auto refer_itr = refers.find(account); 544 | if(refer_itr == refers.end() && user_itr->refer > 0){ 545 | refer_itr = refers.emplace(_self, [&](auto& r){ 546 | r.name = account; 547 | }); 548 | } 549 | auto fee_refer_itr = refers.find(FEE_ACCOUNT); 550 | if(fee_refer_itr == refers.end() && fee_user_itr->refer > 0){ 551 | fee_refer_itr = refers.emplace(_self, [&](auto& r){ 552 | r.name = FEE_ACCOUNT; 553 | }); 554 | } 555 | 556 | user_table next_referinfo(_self, game_itr->next_refer); 557 | auto next_refer_itr = next_referinfo.find(game_itr->gameid); 558 | if(next_refer_itr == next_referinfo.end()){ 559 | _game.modify(game_itr, _self, [&](auto& g){ 560 | g.next_refer = account; 561 | }); 562 | } 563 | } 564 | } 565 | 566 | _game.modify(game_itr, _self, [&](auto& g) { 567 | g.insure += quantity; 568 | }); 569 | } 570 | 571 | void deposit_reward(asset quantity){ 572 | auto game_itr = _game.begin(); 573 | _game.modify(game_itr, _self, [&](auto& g) { 574 | g.reward += quantity; 575 | }); 576 | } 577 | 578 | void stake(account_name account, asset quantity){ 579 | auto game_itr = _game.begin(); 580 | if(account == game_itr->player_one){ 581 | // 当前是头号的用户可以无缝增加抵押CGT,稳住头号的位置 582 | _game.modify(game_itr, _self , [&](auto& g){ 583 | g.staked += quantity; 584 | }); 585 | } else if(quantity > game_itr->staked){ 586 | // 取代当前的头号的位置,并且奖励周期刷新 587 | unstake(game_itr->player_one); 588 | _game.modify(game_itr, _self, [&](auto& g){ 589 | g.staked = quantity; 590 | g.player_one = account; 591 | g.reward_time = now() + _REWARD_COOL_DOWN; 592 | }); 593 | } else { 594 | eosio_assert(false, "需要抵押更多的CGT才能超越当前的头号"); 595 | } 596 | } 597 | 598 | void unstake(account_name account){ 599 | auto game_itr = _game.begin(); 600 | eosio_assert(game_itr->player_one == account, "can only unstake player one's token"); 601 | asset staked = game_itr->staked; 602 | _game.modify(game_itr, _self, [&](auto& g){ 603 | g.staked = asset(0, GAME_SYMBOL); 604 | g.player_one = FEE_ACCOUNT; 605 | }); 606 | if(staked >= asset(1000 * _UNIT, GAME_SYMBOL)){ 607 | // 争取头号的用户将有10%的抵押CGT作为手续费,解除抵押的时候收取 608 | asset fee = staked / 10; 609 | staked -= fee; 610 | _game.modify(game_itr, _self, [&](auto& g) { 611 | g.supply -= fee; 612 | g.circulation -= fee; 613 | g.burn += fee; 614 | }); 615 | 616 | action( 617 | permission_level{_self, N(active)}, 618 | GAME_TOKEN_CONTRACT, N(transfer), 619 | make_tuple(_self, BURN_ACCOUNT, fee, string("解除抵押将损失百分之十的抵押CGT"))) 620 | .send(); 621 | 622 | action( 623 | permission_level{_self, N(active)}, 624 | GAME_TOKEN_CONTRACT, N(transfer), 625 | make_tuple(_self, account, staked, string("可能有其他玩家抵押超越了您,您已经不再是头号。 网址: http://eosplayer.one"))) 626 | .send(); 627 | 628 | action( 629 | permission_level{_self, N(active)}, 630 | TOKEN_CONTRACT, N(transfer), 631 | make_tuple(_self, account, asset(1ll, CORE_SYMBOL), string("可能有其他玩家抵押超越了您,您已经不再是头号。 网址: http://eosplayer.one"))) 632 | .send(); 633 | 634 | claim_reward(game_itr->player_one); 635 | } else if(staked > asset(0, GAME_SYMBOL)){ 636 | _game.modify(game_itr, _self, [&](auto& g) { 637 | g.supply -= staked; 638 | g.circulation -= staked; 639 | g.burn += staked; 640 | }); 641 | 642 | action( 643 | permission_level{_self, N(active)}, 644 | GAME_TOKEN_CONTRACT, N(transfer), 645 | make_tuple(_self, BURN_ACCOUNT, staked, string("抵押CGT太少,将全部损失"))) 646 | .send(); 647 | } 648 | } 649 | 650 | void claim_reward(account_name account){ 651 | auto game_itr = _game.begin(); 652 | eosio_assert(game_itr->player_one == account, "only player one can claim the reward"); 653 | asset reward = game_itr->reward; 654 | // 每一个奖励周期(24小时),头号都能够获得手续费奖池的10%,前提是发送金额大于10EOS 655 | reward.amount = reward.amount / 10; 656 | if( now() >= game_itr->reward_time && reward >= asset(10 * _UNIT, CORE_SYMBOL)){ 657 | _game.modify(game_itr, _self, [&](auto& g){ 658 | g.reward -= reward; 659 | g.reward_time = now() + _REWARD_COOL_DOWN; 660 | }); 661 | action( 662 | permission_level{_self, N(active)}, 663 | TOKEN_CONTRACT, N(transfer), 664 | make_tuple(_self, account, reward, string("头号奖励。 网址: http://eosplayer.one"))) 665 | .send(); 666 | } 667 | } 668 | 669 | void new_user(account_name account, string parent_str, account_name ram_payer){ 670 | auto game_itr = _game.begin(); 671 | user_table userinfo(_self, account); 672 | auto user_itr = userinfo.find(game_itr->gameid); 673 | if(user_itr != userinfo.end()) return; 674 | 675 | uint32_t discount = 0; 676 | auto parent = string_to_name(parent_str.c_str()); 677 | user_table parentinfo(_self, parent); 678 | auto parent_itr = parentinfo.find(game_itr->gameid); 679 | //新用户缺失推荐人的情况下将均匀分配到购买了邀请码的用户 680 | if(parent_itr == parentinfo.end() || parent_itr->refer <= 0 || account == parent){ 681 | //如果没有用户购买邀请码,新用户的上级将默认分配到FEE_ACCOUNT,否则按照推荐人队列依次分配 682 | parent = FEE_ACCOUNT; 683 | user_table next_referinfo(_self, game_itr->next_refer); 684 | auto next_refer_itr = next_referinfo.find(game_itr->gameid); 685 | if(refers.begin() != refers.end() && next_refer_itr != next_referinfo.end()){ 686 | auto refer_itr = refers.find(game_itr->next_refer); 687 | if(refer_itr != refers.end()){ 688 | user_table refer_userinfo(_self, refer_itr->name); 689 | auto refer_user_itr = refer_userinfo.find(game_itr->gameid); 690 | if(refer_user_itr != refer_userinfo.end()){ 691 | parent = refer_user_itr->name; 692 | if(refer_user_itr->refer <= 1){ 693 | refer_itr = refers.erase(refer_itr); 694 | } else { 695 | refer_itr ++; 696 | } 697 | if(refers.begin() == refers.end()){ 698 | _game.modify(game_itr, _self, [&](auto& g){ 699 | g.next_refer = BURN_ACCOUNT; 700 | }); 701 | } else if(refer_itr == refers.end()) { 702 | _game.modify(game_itr, _self, [&](auto& g){ 703 | g.next_refer = refers.begin()->name; 704 | }); 705 | } else { 706 | _game.modify(game_itr, _self, [&](auto& g){ 707 | g.next_refer = refer_itr->name; 708 | }); 709 | } 710 | } 711 | } 712 | } 713 | } else { 714 | if( now() < _GAME_PRESALE_TIME ){ 715 | parentinfo.modify(parent_itr, ram_payer, [&](auto& u){ 716 | u.quota += 1; 717 | }); 718 | } 719 | } 720 | 721 | user_table parent_info(_self, parent); 722 | parent_itr = parent_info.find(game_itr->gameid); 723 | //分配到邀请码的新用户交易手续费减少50% 724 | if(parent_itr->refer > 0){ 725 | discount = 1; 726 | parent_info.modify(parent_itr, ram_payer, [&](auto& u){ 727 | u.refer --; 728 | }); 729 | } 730 | 731 | userinfo.emplace(ram_payer, [&](auto& u) { 732 | u.gameid = game_itr->gameid; 733 | u.name = account; 734 | u.parent = parent; 735 | u.discount = discount; 736 | u.last_action = now(); 737 | }); 738 | } 739 | 740 | void collect_fee(account_name account, asset fee){ 741 | //邀请奖励累积到合约,统一赎回 742 | if (fee.amount > 0){ 743 | //邀请奖励金池与主奖金池隔离 744 | auto game_itr = _game.begin(); 745 | _game.modify(game_itr, _self, [&](auto& g){ 746 | g.fee += fee; 747 | }); 748 | 749 | asset refer_fee = fee; 750 | refer_fee = fee / 2; 751 | fee -= refer_fee; 752 | 753 | user_table userinfo(_self, account); 754 | auto user_itr = userinfo.find(game_itr->gameid); 755 | if(user_itr == userinfo.end()) return; 756 | user_table parentinfo(_self, user_itr->parent); 757 | auto parent_itr = parentinfo.find(game_itr->gameid); 758 | if(parent_itr == parentinfo.end()) return; 759 | //邀请奖励回馈直接上级50% 760 | parentinfo.modify(parent_itr, _self, [&](auto& u){ 761 | u.reward += fee; 762 | }); 763 | 764 | if (refer_fee.amount > 0) 765 | { 766 | user_table second_parentinfo(_self, parent_itr->parent); 767 | auto second_parent_itr = second_parentinfo.find(game_itr->gameid); 768 | if(second_parent_itr == second_parentinfo.end()) return; 769 | //邀请奖励二级回馈50% 770 | second_parentinfo.modify(second_parent_itr, _self, [&](auto& u){ 771 | u.reward += refer_fee; 772 | }); 773 | } 774 | } 775 | } 776 | 777 | void claim_fee(account_name account){ 778 | auto game_itr = _game.begin(); 779 | user_table userinfo(_self, account); 780 | auto user_itr = userinfo.find(game_itr->gameid); 781 | if(user_itr == userinfo.end()) return; 782 | //邀请奖励累积到1EOS及以上才能够赎回 783 | if(user_itr->reward >= asset(_UNIT, CORE_SYMBOL)){ 784 | asset reward = user_itr->reward; 785 | userinfo.modify(user_itr, _self, [&](auto& u){ 786 | u.reward = asset(0, CORE_SYMBOL); 787 | }); 788 | //邀请奖励金池与主奖金池隔离 789 | _game.modify(game_itr, _self, [&](auto& g){ 790 | g.fee -= reward; 791 | }); 792 | //邀请奖励金池与主奖金池隔离 793 | eosio_assert(game_itr->fee >= asset(0, CORE_SYMBOL), "shit happens"); 794 | action( 795 | permission_level{_self, N(active)}, 796 | TOKEN_CONTRACT, N(transfer), 797 | make_tuple(_self, user_itr->name, reward, string("获得邀请奖励。 网址: http://eosplayer.one"))) 798 | .send(); 799 | } 800 | } 801 | 802 | private: 803 | real_type _crr(asset circulation) { 804 | eosio_assert(circulation.amount >= 0, "shit happens"); 805 | real_type A(_A); 806 | real_type B(_B); 807 | real_type L(_L); 808 | real_type D(_D); 809 | real_type ONE(1.0); 810 | real_type H(100.0); 811 | real_type UNIT(_UNIT); 812 | real_type E(2.71828182845904); 813 | 814 | real_type X(circulation.amount); 815 | X = X / UNIT; 816 | 817 | real_type R = ONE / (ONE + pow(E, (X - L) / D)) * A + B; 818 | eosio_assert(R >= B && R <= B + A, "shit happens"); 819 | return R / H; 820 | } 821 | 822 | string name_to_string(account_name name){ 823 | static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz"; 824 | string str(13,'.'); 825 | uint64_t tmp = name; 826 | for( uint32_t i = 0; i <= 12; ++i ) { 827 | char c = charmap[tmp & (i == 0 ? 0x0f : 0x1f)]; 828 | str[12-i] = c; 829 | tmp >>= (i == 0 ? 4 : 5); 830 | } 831 | const auto last = str.find_last_not_of('.'); 832 | if (last != string::npos) 833 | str = str.substr(0, last + 1); 834 | return str; 835 | } 836 | 837 | // @abi table game i64 838 | struct game{ 839 | account_name gameid; 840 | asset reserve = asset(0, CORE_SYMBOL); 841 | asset insure = asset(0, CORE_SYMBOL); 842 | asset max_supply = asset(0, CORE_SYMBOL); 843 | asset supply = asset(0, GAME_SYMBOL); 844 | asset balance = asset(0, GAME_SYMBOL); 845 | asset circulation = asset(0, GAME_SYMBOL); 846 | asset burn = asset(0, GAME_SYMBOL); 847 | asset staked = asset(0, GAME_SYMBOL); 848 | asset fee = asset(0, CORE_SYMBOL); 849 | asset reward = asset(0, CORE_SYMBOL); 850 | account_name next_refer = FEE_ACCOUNT; 851 | account_name player_one = FEE_ACCOUNT; 852 | uint64_t start_time; 853 | uint64_t reward_time; 854 | 855 | uint64_t primary_key() const { return gameid; } 856 | EOSLIB_SERIALIZE(game, (gameid)(reserve)(insure)(max_supply)(supply)(balance)(circulation)(burn)(staked)(fee)(reward)(next_refer)(player_one)(start_time)(reward_time)) 857 | }; 858 | typedef eosio::multi_index game_table; 859 | game_table _game; 860 | 861 | // @abi table userinfo i64 862 | struct user{ 863 | account_name gameid; 864 | account_name name; 865 | account_name parent; 866 | asset reward = asset(0, CORE_SYMBOL); 867 | uint64_t last_action; 868 | uint64_t refer = 0; 869 | uint64_t quota = 0; 870 | uint32_t discount = 0; 871 | 872 | uint64_t primary_key() const { return gameid; } 873 | EOSLIB_SERIALIZE(user, (gameid)(name)(parent)(reward)(last_action)(refer)(quota)(discount)) 874 | }; 875 | typedef eosio::multi_index user_table; 876 | // user_table userinfo; 877 | 878 | // @abi table refers i64 879 | struct refer{ 880 | account_name name; 881 | uint64_t primary_key() const { return name; } 882 | EOSLIB_SERIALIZE(refer, (name)) 883 | }; 884 | typedef eosio::multi_index refer_table; 885 | refer_table refers; 886 | 887 | // @abi table invitations i64 888 | struct invitation{ 889 | account_name to; 890 | account_name from; 891 | uint64_t primary_key() const { return to; } 892 | EOSLIB_SERIALIZE(invitation, (to)(from)) 893 | }; 894 | typedef eosio::multi_index invitation_table; 895 | invitation_table invitations; 896 | }; 897 | 898 | #define EOSIO_ABI_EX( TYPE, MEMBERS ) \ 899 | extern "C" { \ 900 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \ 901 | auto self = receiver; \ 902 | if(action == N(onerror)) { \ 903 | /* onerror is only valid if it is for the "eosio" code account and authorized by "eosio"'s "active permission */ \ 904 | eosio_assert(code == N(eosio), "onerror action's are only valid from the \"eosio\" system account"); \ 905 | } \ 906 | if(action == N(transfer)) { \ 907 | auto _action = N(onerror); \ 908 | if(code == TOKEN_CONTRACT) { \ 909 | _action = N(eosio_token_transfer); \ 910 | } else if(code == GAME_TOKEN_CONTRACT) { \ 911 | _action = N(game_token_transfer); \ 912 | } \ 913 | if(_action == N(onerror)) { \ 914 | eosio_assert(false, "action from this code is denied"); \ 915 | } \ 916 | TYPE thiscontract( self ); \ 917 | switch( _action ) { \ 918 | EOSIO_API( TYPE, MEMBERS ) \ 919 | } \ 920 | /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \ 921 | } \ 922 | } \ 923 | } \ 924 | 925 | EOSIO_ABI_EX(playerone, (eosio_token_transfer)(game_token_transfer)) -------------------------------------------------------------------------------- /playerone_buy.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "3.0000 EOS", "deposit"]' -p testuseraaaa 4 | 5 | for ((i=0; i<1; ++i)) 6 | do 7 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "99.9999 EOS", "testuseraaaa"]' -p testuseraaaa 8 | cleos push action eosio.token transfer '["testuseraaab", "oneplayerone", "99.9999 EOS", "testuseraaaa"]' -p testuseraaab 9 | cleos push action eosio.token transfer '["testuseraaac", "oneplayerone", "99.9999 EOS", "testuseraaab"]' -p testuseraaac 10 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaad 11 | cleos push action eosio.token transfer '["testuseraaae", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaae 12 | cleos push action eosio.token transfer '["testuseraaaf", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaaf 13 | cleos push action eosio.token transfer '["testuseraaag", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaag 14 | cleos push action eosio.token transfer '["testuseraaah", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaah 15 | cleos push action eosio.token transfer '["testuseraaai", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaai 16 | cleos push action eosio.token transfer '["testuseraaaj", "oneplayerone", "99.9999 EOS", ""]' -p testuseraaaj 17 | 18 | cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaaa 19 | cleos push action playeroneiss transfer '["testuseraaab", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaab 20 | cleos push action playeroneiss transfer '["testuseraaac", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaac 21 | cleos push action playeroneiss transfer '["testuseraaad", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaad 22 | cleos push action playeroneiss transfer '["testuseraaae", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaae 23 | cleos push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaaf 24 | cleos push action playeroneiss transfer '["testuseraaag", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaag 25 | cleos push action playeroneiss transfer '["testuseraaah", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaah 26 | cleos push action playeroneiss transfer '["testuseraaai", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaai 27 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "11.1111 CGT", ""]' -p testuseraaaj 28 | 29 | done 30 | 31 | cleos get table oneplayerone oneplayerone game 32 | cleos get table oneplayerone oneplayerone users 33 | cleos get table oneplayerone oneplayerone refers -------------------------------------------------------------------------------- /playerone_init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # assume you have imported the officials' keys 4 | cleos wallet import --private-key 5KaVNWNF2LtdxBT8fGUV81yXZjKiu7qdR28myrUKEXcem8gc1qy 5 | cleos wallet import --private-key 5KNGa5bkAW8sP5dqcYNHQSvAXQtsfU9yyLr87SBvE7F3RyonUZ1 6 | cleos wallet import --private-key 5JdthYKccniLB7w5VQegU4HkERpzMD9yQ1hK3AJvduZKAr9EoeT 7 | cleos wallet import --private-key 5K5rvrLPKP9tNkLngX9vJcLDYeh6nAurakb2Xwc2CpaRaAwazZ4 8 | 9 | 10 | # blackholeeos = EOS5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi=KEY:5KaVNWNF2LtdxBT8fGUV81yXZjKiu7qdR28myrUKEXcem8gc1qy 11 | cleos create account eosio blackholeeos EOS5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi EOS5PW5ZchfiCF2uPuFUEt8xseS1wiNqBjCHQTYxXT3unLNamrpwi 12 | 13 | # playeronefee = EOS7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza=KEY:5KNGa5bkAW8sP5dqcYNHQSvAXQtsfU9yyLr87SBvE7F3RyonUZ1 14 | cleos create account eosio playeronefee EOS7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza EOS7AH473AJ1Dix3x7SjMU9tjsG7Fo79JZq9GuZjL9f5FCu6rUhza 15 | 16 | # oneplayerone = EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go=KEY:5JdthYKccniLB7w5VQegU4HkERpzMD9yQ1hK3AJvduZKAr9EoeT 17 | cleos create account eosio oneplayerone EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go 18 | # cleos system newaccount eosio oneplayerone EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go --stake-net "10.0000 SYS" --stake-cpu "10.0000 SYS" --buy-ram-kbytes 1000 19 | 20 | # playeroneiss = EOS8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo=KEY:5K5rvrLPKP9tNkLngX9vJcLDYeh6nAurakb2Xwc2CpaRaAwazZ4 21 | cleos create account eosio playeroneiss EOS8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo EOS8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo 22 | # cleos system newaccount eosio playeroneiss EOS8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo EOS8cgtXLQLtAzRyNytCLdvZGMaixKrt9nmoUkBY4MfULriSg4Uzo --stake-net "10.0000 SYS" --stake-cpu "10.0000 SYS" --buy-ram-kbytes 10000 23 | 24 | # cleos set contract oneplayerone ./build/playerone -p oneplayerone 25 | cleos set code oneplayerone ./build/playerone/playerone.wasm -p oneplayerone 26 | cleos set abi oneplayerone ./build/playerone/playerone.abi -p oneplayerone 27 | 28 | cleos set contract playeroneiss ./build/eosio.token -p playeroneiss 29 | cleos push action playeroneiss create '[ "oneplayerone", "250000000.0000 CGT"]' -p playeroneiss 30 | 31 | cleos set account permission oneplayerone active '{"threshold": 1,"keys": [{"key": "EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go","weight": 1}],"accounts": [{"permission":{"actor":"oneplayerone","permission":"eosio.code"},"weight":1}]}' owner -p oneplayerone 32 | 33 | # follow test must throw 34 | # cleos push action playeroneiss create '[ "playeronefee", "10000000.0000 EOS"]' -p playeroneiss 35 | # cleos push action playeroneiss issue '[ "playeronefee", "100000.0000 EOS"]' -p playeronefee 36 | # cleos push action playeroneiss transfer '["playeronefee", "oneplayerone", "10.1111 EOS", "testuseraaaa"]' -p playeronefee 37 | 38 | # follow test must throw 39 | # cleos set contract playeronefee ./build/eosio.token -p playeronefee 40 | # cleos push action playeronefee create '[ "playeronefee", "10000000.0000 EOS"]' -p playeronefee 41 | # cleos push action playeronefee create '[ "playeronefee", "10000000.0000 CGT"]' -p playeronefee 42 | # cleos push action playeronefee issue '[ "playeronefee", "10000000.0000 EOS", "initial supply" ]' -p playeronefee 43 | # cleos push action playeronefee issue '[ "playeronefee", "10000000.0000 CGT", "initial supply" ]' -p playeronefee 44 | # cleos push action playeronefee transfer '["playeronefee", "oneplayerone", "10.1111 EOS", "testuseraaaa"]' -p playeronefee 45 | # cleos push action playeronefee transfer '["playeronefee", "oneplayerone", "10.1111 CGT", "testuseraaaa"]' -p playeronefee 46 | -------------------------------------------------------------------------------- /playerone_main_init.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | EOS_RPC=https://mainnet-eos.token.im 4 | alias cleos_mainnet="cleos -u $EOS_RPC" 5 | 6 | # assume you have imported the officials' keys 7 | 8 | # cleos set contract oneplayerone ./build/playerone -p oneplayerone 9 | 10 | # cleos set code oneplayerone ./build/playerone/playerone.wasm -p oneplayerone 11 | # cleos set abi oneplayerone ./build/playerone/playerone.abi -p oneplayerone 12 | 13 | cleos_mainnet set contract playeroneiss ./build/eosio.token -p playeroneiss 14 | 15 | # cleos push action playeroneiss create '[ "oneplayerone", "10000000.0000 CGT"]' -p playeroneiss 16 | 17 | # cleos set account permission oneplayerone active '{"threshold": 1,"keys": [{"key": "EOS4wen3kfDXSHEb4nYmzDkcfvoPZb2jyoRS6mb6EbGJgM5Apu6Go","weight": 1}],"accounts": [{"permission":{"actor":"oneplayerone","permission":"eosio.code"},"weight":1}]}' owner -p oneplayerone 18 | 19 | # follow test must throw 20 | # cleos push action playeroneiss create '[ "playeronefee", "10000000.0000 EOS"]' -p playeroneiss 21 | # cleos push action playeroneiss issue '[ "playeronefee", "100000.0000 EOS"]' -p playeronefee 22 | # cleos push action playeroneiss transfer '["playeronefee", "oneplayerone", "10.1111 EOS", "testuseraaaa"]' -p playeronefee 23 | -------------------------------------------------------------------------------- /playerone_presale.sh: -------------------------------------------------------------------------------- 1 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaab"]' -p testuseraaaa 2 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaac"]' -p testuseraaaa 3 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaad"]' -p testuseraaaa 4 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaae"]' -p testuseraaaa 5 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaaf"]' -p testuseraaaa 6 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaag"]' -p testuseraaaa 7 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaah"]' -p testuseraaaa 8 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaai"]' -p testuseraaaa 9 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "0.0001 EOS", "testuseraaaj"]' -p testuseraaaa 10 | # cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "100.0001 EOS", "testuseraaaj"]' -p testuseraaaa 11 | 12 | 13 | 14 | cleos get table oneplayerone testuseraaaa userinfo 15 | cleos get table oneplayerone testuseraaab userinfo 16 | cleos get table oneplayerone testuseraaac userinfo 17 | cleos get table oneplayerone testuseraaad userinfo 18 | cleos get table oneplayerone testuseraaae userinfo 19 | cleos get table oneplayerone testuseraaaf userinfo 20 | cleos get table oneplayerone testuseraaag userinfo 21 | cleos get table oneplayerone testuseraaah userinfo 22 | cleos get table oneplayerone testuseraaai userinfo 23 | cleos get table oneplayerone testuseraaaj userinfo 24 | 25 | cleos get table oneplayerone oneplayerone refers 26 | cleos get table oneplayerone oneplayerone game 27 | cleos get table oneplayerone oneplayerone invitations -------------------------------------------------------------------------------- /playerone_sell.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | for ((i=0; i<1; ++i)) 4 | do 5 | cleos push action eosio.token transfer '["testuseraaaa", "oneplayerone", "1.1111 EOS", "testuseraaaa"]' -p testuseraaaa 6 | cleos push action eosio.token transfer '["testuseraaab", "oneplayerone", "1.1111 EOS", "testuseraaaa"]' -p testuseraaab 7 | cleos push action eosio.token transfer '["testuseraaac", "oneplayerone", "1.1111 EOS", "testuseraaab"]' -p testuseraaac 8 | cleos push action eosio.token transfer '["testuseraaad", "oneplayerone", "1.1111 EOS", ""]' -p testuseraaad 9 | cleos push action eosio.token transfer '["testuseraaae", "oneplayerone", "1.1111 EOS", "testuseraaaa"]' -p testuseraaae 10 | cleos push action eosio.token transfer '["testuseraaaf", "oneplayerone", "1.1111 EOS", "testuseraaaa"]' -p testuseraaaf 11 | cleos push action eosio.token transfer '["testuseraaag", "oneplayerone", "1.1111 EOS", "testuseraaab"]' -p testuseraaag 12 | cleos push action eosio.token transfer '["testuseraaah", "oneplayerone", "1.1111 EOS", ""]' -p testuseraaah 13 | cleos push action eosio.token transfer '["testuseraaai", "oneplayerone", "1.1111 EOS", "testuseraaab"]' -p testuseraaai 14 | cleos push action eosio.token transfer '["testuseraaaj", "oneplayerone", "1.1111 EOS", ""]' -p testuseraaaj 15 | 16 | cleos push action playeroneiss transfer '["testuseraaaa", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaaa 17 | cleos push action playeroneiss transfer '["testuseraaab", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaab 18 | cleos push action playeroneiss transfer '["testuseraaac", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaac 19 | cleos push action playeroneiss transfer '["testuseraaad", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaad 20 | cleos push action playeroneiss transfer '["testuseraaae", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaae 21 | cleos push action playeroneiss transfer '["testuseraaaf", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaaf 22 | cleos push action playeroneiss transfer '["testuseraaag", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaag 23 | cleos push action playeroneiss transfer '["testuseraaah", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaah 24 | cleos push action playeroneiss transfer '["testuseraaai", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaai 25 | cleos push action playeroneiss transfer '["testuseraaaj", "oneplayerone", "111.1111 CGT", ""]' -p testuseraaaj 26 | 27 | done 28 | 29 | cleos get table oneplayerone oneplayerone game 30 | cleos get table oneplayerone oneplayerone users -------------------------------------------------------------------------------- /playerone_stake.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dabdevelop/playerone/c8e41c910358ea8ec9c1911827b4ef7a91863025/playerone_stake.sh -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # before run it you may need to unlock eos wallet 4 | # cleos wallet unlock 5 | 6 | ./build.sh 7 | ./eos_init.sh 8 | ./playerone_init.sh 9 | # ./playerone_buy.sh 10 | ./playerone.sh 11 | -------------------------------------------------------------------------------- /scripts.txt: -------------------------------------------------------------------------------- 1 | docker run --rm --name eosio -d -p 8888:8888 -p 9876:9876 -v /tmp/work:/work -v /tmp/eosio/data:/mnt/dev/data -v /tmp/eosio/config:/mnt/dev/config eosio/eos-dev /bin/bash -c "nodeos -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::wallet_plugin --plugin eosio::producer_plugin --plugin eosio::history_plugin --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --plugin eosio::http_plugin -d /mnt/dev/data --config-dir /mnt/dev/config --http-server-address=0.0.0.0:8888 --access-control-allow-origin=* --contracts-console --http-validate-host=false" 2 | 3 | alias cleos='docker exec -it eosio /opt/eosio/bin/cleos -u http://0.0.0.0:8888 --wallet-url http://0.0.0.0:8888' 4 | 5 | rm -rf ~/Library/Application\ Support/eosio/nodeos/data/* 6 | 7 | ./programs/nodeos/nodeos -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | const ecc = require('eosjs-ecc') 2 | 3 | function generateSignatureProvider(amount){ 4 | for(var i = 0; i < amount; i++){ 5 | ecc.randomKey().then(privateKey => { 6 | // signature-provider = EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 7 | console.log('signature-provider =', ecc.privateToPublic(privateKey)+'=KEY:'+privateKey); 8 | }) 9 | } 10 | } 11 | 12 | 13 | function generateTesters(amount){ 14 | var j = 0x61; 15 | // for(var i = 0; i < amount; i++){ 16 | // ecc.randomKey().then(privateKey=>{ 17 | // console.log('# testuser' + ('aaa' + String.fromCharCode(j)),'=', ecc.privateToPublic(privateKey) + '=KEY:' + privateKey); 18 | // console.log('cleos create account eosio', 'testuser' + ('aaa' + String.fromCharCode(j)), ecc.privateToPublic(privateKey), ecc.privateToPublic(privateKey)); 19 | // j++; 20 | // }); 21 | // } 22 | 23 | 24 | for(var i = 0; i < amount; i++){ 25 | // cleos transfer eosio.token testuser1111 "10000 EOS" "test" -p eosio.token 26 | console.log('cleos transfer eosio.token testuser'+ ('aaa' + String.fromCharCode(0x61 + i)) +' "10000 EOS" "test" -p eosio.token'); 27 | } 28 | } 29 | 30 | function generateOfficialAccount(names){ 31 | // testers = [name1, name2] 32 | var i = 0; 33 | for(var n in names){ 34 | ecc.randomKey().then(privateKey=>{ 35 | console.log('# ' + names[i],'=', ecc.privateToPublic(privateKey) + '=KEY:' + privateKey); 36 | console.log('cleos create account eosio', names[i], ecc.privateToPublic(privateKey), ecc.privateToPublic(privateKey)); 37 | // console.log('cleos transfer eosio.token '+ names[i] +' "10000 EOS" "test" -p eosio.token'); 38 | i++; 39 | }); 40 | } 41 | } 42 | 43 | // generateTesters(10); 44 | // generateOfficialAccount(['eosplayerone', 'oneplayerone', 'blackholeeos', 'playeronefee', 'playeroneiss']) 45 | generateOfficialAccount(['enuplayerone']); 46 | 47 | // generateSignatureProvider(amount) --------------------------------------------------------------------------------