├── .babelrc
├── .gitignore
├── LICENSE
├── README.md
├── config.js
├── contracts
├── todo.abi
└── todo.js
├── dapp
├── components
│ ├── app.js
│ ├── footer.js
│ ├── header.js
│ ├── main-section.js
│ ├── todo-item.js
│ └── todo-text-input.js
└── index.js
├── dist
└── index.html
├── package-lock.json
├── package.json
├── scripts
├── deploy.js
├── server.js
└── webpack.dev.js
├── start_fibos
└── node.js
└── test
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [["@babel/env"], ["@babel/preset-react"]],
3 | "plugins": [
4 | "@babel/plugin-proposal-object-rest-spread",
5 | "transform-class-properties",
6 | "@babel/plugin-transform-arrow-functions"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | # fibos blockchain data
64 | start_fibos/fibos_data_dir/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Shawn Xie
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FIBOS TodoMVC
2 | Todo DApp for FIBOS blockchain by React and fibos.js
3 |
4 | ## Installation
5 |
6 | You need install FIBOS first:
7 |
8 | ```
9 | curl -s https://fibos.io/download/installer.sh | sh
10 | ```
11 |
12 | Then check FIBOS version:
13 |
14 | ```
15 | ~$ which fibos
16 | /usr/local/bin/fibos
17 |
18 | ~$ fibos --version
19 | v0.27.0-dev
20 | ```
21 |
22 | Install packages:
23 |
24 | ```
25 | npm install
26 | ```
27 |
28 | ## Setup and run
29 |
30 | Launch FIBOS local net:
31 |
32 | ```
33 | npm run start:fibos
34 | ```
35 |
36 | Deploy the contract to FIBOS local net:
37 |
38 | ```
39 | npm run deploy:contract
40 | ```
41 |
42 | Run Todo DApp:
43 |
44 | ```
45 | npm run start:dapp
46 | ```
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | client: {
3 | chainId: 'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f',
4 | httpEndpoint: 'http://127.0.0.1:8888',
5 | keyProvider: process.env.PRIVATE_KEY || '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
6 | },
7 | contract: {
8 | name: 'todo',
9 | sender: 'todo'
10 | },
11 | testContract:{
12 | name: 'testtodo',
13 | sender: 'testtodo'
14 | },
15 | account: {
16 | publicKey: process.env.PUBLIC_KEY || 'FO6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV',
17 | privateKey: process.env.PRIVATE_KEY || '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
18 | }
19 | }
20 |
21 | module.exports = config
--------------------------------------------------------------------------------
/contracts/todo.abi:
--------------------------------------------------------------------------------
1 | {
2 | "version": "eosio::abi/1.0",
3 | "structs": [
4 | {
5 | "name": "todo_index",
6 | "base": "",
7 | "fields": [
8 | {
9 | "name": "id",
10 | "type": "int64"
11 | }
12 | ]
13 | },
14 | {
15 | "name": "todo",
16 | "base" : "",
17 | "fields": [
18 | {
19 | "name": "id",
20 | "type": "int64"
21 | },
22 | {
23 | "name": "text",
24 | "type": "string"
25 | },
26 | {
27 | "name": "completed",
28 | "type": "bool"
29 | }
30 | ]
31 | }
32 | ],
33 | "actions": [
34 | {
35 | "name": "emplacetodo",
36 | "type": "todo",
37 | "ricardian_contract": ""
38 | },
39 | {
40 | "name": "findtodo",
41 | "type": "todo_index",
42 | "ricardian_contract": ""
43 | },
44 | {
45 | "name": "updatetodo",
46 | "type": "todo",
47 | "ricardian_contract": ""
48 | },
49 | {
50 | "name": "destorytodo",
51 | "type": "todo_index",
52 | "ricardian_contract": ""
53 | }
54 | ],
55 | "tables": [
56 | {
57 | "name": "todos",
58 | "type": "todo",
59 | "index_type": "i64",
60 | "key_names": ["id"],
61 | "key_types": ["int64"]
62 | }
63 | ]
64 | }
--------------------------------------------------------------------------------
/contracts/todo.js:
--------------------------------------------------------------------------------
1 | // create 似乎是个关键词
2 | exports.emplacetodo = (id, text, completed) => {
3 | var todos = db.todos(action.account, action.account);
4 | todos.emplace(action.account, {
5 | text,
6 | completed,
7 | id
8 | });
9 | console.log('todo#', id, ' created');
10 | }
11 | exports.findtodo = (id) => {
12 | var todos = db.todos(action.account, action.account);
13 | console.log(todos.find(id))
14 | };
15 | exports.updatetodo = (id, text, completed) => {
16 | var todos = db.todos(action.account, action.account);
17 | var itr = todos.find(id);
18 | itr.data.text = text;
19 | itr.data.completed = completed;
20 | itr.update(action.account);
21 | console.log('todos#', id, ' updated');
22 | }
23 | exports.destorytodo = (id) => {
24 | var todos = db.todos(action.account, action.account);
25 | var itr = todos.find(id);
26 | itr.remove();
27 | console.log('todos#', id, ' removed');
28 | }
--------------------------------------------------------------------------------
/dapp/components/app.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import Header from './header'
3 | import MainSection from './main-section'
4 | // import EOS from 'eosjs'
5 | import FIBOS from 'fibos.js'
6 | import config from '../../config'
7 |
8 | // const eosClient = EOS(config.clientConfig)
9 | const fibosClient = FIBOS(config.client)
10 |
11 | const initialState = [
12 | {
13 | text: 'React ES6 TodoMVC',
14 | completed: 0,
15 | id: 0
16 | }
17 | ]
18 |
19 | class App extends Component {
20 | constructor(props) {
21 | super(props)
22 | this.state = {
23 | todos: [] || initialState,
24 | gameID: null,
25 | player: 0
26 | }
27 | this.fetchTodo()
28 | }
29 |
30 | fetchTodo = () => {
31 | fibosClient.getTableRows(
32 | true,
33 | config.contract.sender,
34 | config.contract.name,
35 | 'todos').then((data)=>{
36 | this.setState({todos: data.rows})
37 | }).catch((e) => {
38 | console.error(e)
39 | }
40 | )
41 | }
42 |
43 | addTodo = (text) => {
44 | const todo_id = this.state.todos.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1
45 | fibosClient.contract(config.contract.name).then((contract) => {
46 | contract.emplacetodo(
47 | {
48 | id: todo_id,
49 | text,
50 | completed: 0
51 | },
52 | { authorization: [config.contract.sender] }
53 | ).then((res) => {
54 | const todos = [
55 | {
56 | id: todo_id,
57 | completed: 0,
58 | text: text
59 | },
60 | ...this.state.todos
61 | ]
62 | this.setState({todos})
63 | }
64 | )
65 | .catch((err) => { console.log(err) })
66 | })
67 | }
68 |
69 | deleteTodo = (id) => {
70 | fibosClient.contract(config.contract.name).then((contract) => {
71 | contract.destorytodo(
72 | {
73 | id
74 | },
75 | { authorization: [config.contract.sender]}
76 | ).then((res) => {
77 | const todos = this.state.todos.filter(todo => todo.id !== id)
78 | this.setState({todos})
79 | })
80 | .catch((err) => {
81 | console.log(err)
82 | })
83 | })
84 | }
85 |
86 | editTodo = (id, text) => {
87 | const todo_item = this.state.todos.find((el) => el.id === id)
88 | if (!todo_item){
89 | return
90 | }
91 | fibosClient.contract(config.contract.name).then((contract) => {
92 | contract.updatetodo(
93 | {
94 | id: id,
95 | text,
96 | completed: todo_item.completed
97 | },
98 | { authorization: [config.contract.sender] }
99 | ).then((res) => {
100 | const todos = this.state.todos.map(todo =>
101 | todo.id === id ? {...todo, text} : todo
102 | )
103 | this.setState({todos})
104 | }
105 | )
106 | .catch((err) => { console.log(err) })
107 | })
108 | }
109 |
110 | completeTodo = (id) => {
111 | const todo_item = this.state.todos.find((el) => el.id === id)
112 | if (!todo_item){
113 | return
114 | }
115 | fibosClient.contract(config.contract.name).then((contract) => {
116 | contract.updatetodo(
117 | {
118 | id: id,
119 | text: todo_item.text,
120 | completed: todo_item.completed === 1?0:1
121 | },
122 | { authorization: [config.contract.sender] }
123 | ).then((res) => {
124 | const todos = this.state.todos.map(todo =>
125 | todo.id === id ? {...todo, completed: !todo.completed} : todo
126 | )
127 | this.setState({todos})
128 | }
129 | )
130 | .catch((err) => { console.log(err) })
131 | })
132 | }
133 |
134 | clearCompleted = () => {
135 | const todos = this.state.todos.filter(todo => todo.completed === 0)
136 | this.setState({todos})
137 | }
138 |
139 | actions = {
140 | addTodo: this.addTodo,
141 | deleteTodo: this.deleteTodo,
142 | editTodo: this.editTodo,
143 | completeTodo: this.completeTodo,
144 | clearCompleted: this.clearCompleted
145 | }
146 |
147 | render() {
148 | return(
149 |
150 |
151 |
152 |
153 | )
154 | }
155 | }
156 |
157 | export default App
--------------------------------------------------------------------------------
/dapp/components/footer.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import PropTypes from 'prop-types'
3 | import classnames from 'classnames'
4 |
5 | const FILTER_TITLES = {
6 | SHOW_ALL: 'All',
7 | SHOW_ACTIVE: 'Active',
8 | SHOW_COMPLETED: 'Completed'
9 | }
10 |
11 | export default class Footer extends Component {
12 | static propTypes = {
13 | completedCount: PropTypes.number.isRequired,
14 | activeCount: PropTypes.number.isRequired,
15 | filter: PropTypes.string.isRequired,
16 | onClearCompleted: PropTypes.func.isRequired,
17 | onShow: PropTypes.func.isRequired
18 | }
19 |
20 | renderTodoCount() {
21 | const {activeCount} = this.props
22 |
23 | const itemWord = activeCount === 1 ? 'item' : 'items'
24 |
25 | return (
26 |
27 | {activeCount || 'No'}
28 | {itemWord} left
29 |
30 | )
31 | }
32 |
33 | renderFilterLink(filter) {
34 | const title = FILTER_TITLES[filter]
35 | const {filter: selectedFilter, onShow} = this.props
36 |
37 | return (
38 | onShow(filter)}>
42 | {title}
43 |
44 | )
45 | }
46 |
47 | renderClearButton() {
48 | const {completedCount, onClearCompleted} = this.props
49 | if (completedCount > 0) {
50 | return (
51 |
54 | )
55 | }
56 | }
57 |
58 | renderFilterList() {
59 | return ['SHOW_ALL', 'SHOW_ACTIVE', 'SHOW_COMPLETED']
60 | .map(filter =>
61 |
62 | {this.renderFilterLink(filter)}
63 |
64 | )
65 | }
66 |
67 | render() {
68 | return (
69 |
80 | )
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/dapp/components/header.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types';
3 | import TodoTextInput from './todo-text-input'
4 |
5 | const Header = ({addTodo}) => {
6 |
7 | const handleSave = text => {
8 | if (text.length !== 0) {
9 | addTodo(text)
10 | }
11 | }
12 |
13 | return (
14 |
22 | )
23 | }
24 |
25 | Header.propTypes = {
26 | addTodo: PropTypes.func.isRequired
27 | }
28 |
29 | export default Header
30 |
--------------------------------------------------------------------------------
/dapp/components/main-section.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import PropTypes from 'prop-types';
3 | import TodoItem from './todo-item'
4 | import Footer from './footer'
5 |
6 | const TODO_FILTERS = {
7 | SHOW_ALL: () => true,
8 | SHOW_ACTIVE: todo => !todo.completed,
9 | SHOW_COMPLETED: todo => todo.completed
10 | }
11 |
12 | export default class MainSection extends Component {
13 | static propTypes = {
14 | todos: PropTypes.array.isRequired,
15 | actions: PropTypes.object.isRequired
16 | }
17 |
18 | state = { filter: 'SHOW_ALL' }
19 |
20 | handleClearCompleted = () => {
21 | this.props.actions.clearCompleted()
22 | }
23 |
24 | handleShow = filter => {
25 | this.setState({ filter })
26 | }
27 |
28 | // renderToggleAll(completedCount) {
29 | // const { todos, actions } = this.props
30 | // if (todos.length > 0) {
31 | // return (
32 | //
38 | // )
39 | // }
40 | // }
41 |
42 | renderFooter(completedCount) {
43 | const { todos } = this.props
44 | const { filter } = this.state
45 | const activeCount = todos.length - completedCount
46 |
47 | if (todos.length) {
48 | return (
49 |
55 | )
56 | }
57 | }
58 |
59 | render() {
60 | const { todos, actions } = this.props
61 | const { filter } = this.state
62 |
63 | const filteredTodos = todos.filter(TODO_FILTERS[filter])
64 | const completedCount = todos.reduce((count, todo) => {
65 | return todo.completed ? count + 1 : count
66 | }, 0)
67 |
68 | return (
69 |
70 | {/* {this.renderToggleAll(completedCount)} */}
71 |
72 | {filteredTodos.map(todo =>
73 |
74 | )}
75 |
76 | {this.renderFooter(completedCount)}
77 |
78 | )
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/dapp/components/todo-item.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import PropTypes from 'prop-types';
3 | import classnames from 'classnames'
4 | import TodoTextInput from './todo-text-input'
5 |
6 | export default class TodoItem extends Component {
7 | static propTypes = {
8 | todo: PropTypes.object.isRequired,
9 | editTodo: PropTypes.func.isRequired,
10 | deleteTodo: PropTypes.func.isRequired,
11 | completeTodo: PropTypes.func.isRequired
12 | }
13 |
14 | state = {
15 | editing: false
16 | }
17 |
18 | handleDoubleClick = () => {
19 | this.setState({ editing: true })
20 | }
21 |
22 | handleSave = (id, text) => {
23 | if (text.length === 0) {
24 | this.props.deleteTodo(id)
25 | } else {
26 | this.props.editTodo(id, text)
27 | }
28 | this.setState({ editing: false })
29 | }
30 |
31 | render() {
32 | const {todo, completeTodo, deleteTodo} = this.props
33 |
34 | let element
35 | if (this.state.editing) {
36 | element = (
37 | this.handleSave(todo.id, text)}
41 | />
42 | )
43 | } else {
44 | element = (
45 |
46 | completeTodo(todo.id)}
51 | />
52 |
53 |
55 | )
56 | }
57 |
58 | return (
59 |
63 | {element}
64 |
65 | )
66 | }
67 | }
--------------------------------------------------------------------------------
/dapp/components/todo-text-input.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import PropTypes from 'prop-types'
3 | import classnames from 'classnames'
4 |
5 | export default class TodoTextInput extends Component {
6 | static propTypes = {
7 | onSave: PropTypes.func.isRequired,
8 | text: PropTypes.string,
9 | placeholder: PropTypes.string,
10 | editing: PropTypes.bool,
11 | newTodo: PropTypes.bool
12 | }
13 |
14 | state = {
15 | text: this.props.text || ''
16 | }
17 |
18 | handleSubmit = e => {
19 | const text = e.target.value.trim()
20 | if (e.which === 13) {
21 | this.props.onSave(text)
22 | if (this.props.newTodo) {
23 | this.setState({text: ''})
24 | }
25 | }
26 | }
27 |
28 | handleChange = e => this.setState({text: e.target.value})
29 |
30 | handleBlur = e => {
31 | if (!this.props.newTodo) {
32 | this.props.onSave(e.target.value)
33 | }
34 | }
35 |
36 | render() {
37 | return (
38 |
50 | )
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/dapp/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {render} from 'react-dom'
3 | import App from './components/app'
4 | // import TodoList from './todolist'
5 |
6 | import 'todomvc-app-css/index.css'
7 |
8 | render(
9 | ,document.getElementById('root')
10 | )
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React TodoMVC Example
7 |
8 |
9 |
10 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "todolist-fibos-client",
3 | "version": "1.0.0",
4 | "description": "",
5 | "repository": "",
6 | "keywords": "",
7 | "author": "",
8 | "license": "MIT",
9 | "scripts": {
10 | "start:dapp": "node scripts/server.js",
11 | "start:fibos": "fibos start_fibos/node.js",
12 | "deploy:contract": "fibos scripts/deploy.js",
13 | "clean:fibos": "rm -rf start_fibos/fibos_data_dir"
14 | },
15 | "dependencies": {
16 | "classnames": "^2.2.6",
17 | "fibos.js": "^0.3.2",
18 | "prop-types": "^15.6.2",
19 | "react": "^16.5.2",
20 | "react-dom": "^16.5.2",
21 | "todomvc-app-css": "^2.1.2"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "^7.1.0",
25 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
26 | "@babel/plugin-transform-arrow-functions": "^7.0.0",
27 | "@babel/preset-env": "^7.1.0",
28 | "@babel/preset-react": "^7.0.0",
29 | "babel-loader": "^8.0.2",
30 | "babel-plugin-transform-class-properties": "^6.24.1",
31 | "css-loader": "^1.0.0",
32 | "koa": "^2.5.3",
33 | "koa-bodyparser": "^4.2.1",
34 | "koa-static": "^5.0.0",
35 | "koa-webpack": "^3.0.2",
36 | "style-loader": "^0.23.0",
37 | "webpack": "^4.19.1",
38 | "webpack-cli": "^3.1.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/scripts/deploy.js:
--------------------------------------------------------------------------------
1 | const FIBOS = require('fibos.js');
2 | const config = require('../config');
3 | // new FIBOS client
4 | const fibosClient = FIBOS(config.client);
5 | const fs = require('fs');
6 |
7 | // create account
8 | try {
9 | const user = fibosClient.getAccountSync('todo');
10 | console.log('user: ', user);
11 | } catch (error) {
12 | fibosClient.newaccountSync({
13 | creator: 'eosio',
14 | name: 'todo',
15 | owner: config.account.publicKey,
16 | active: config.account.publicKey,
17 | });
18 | console.log('create account successfully');
19 | }
20 |
21 | // setcode
22 | const jsCode = fs.readTextFile(`${__dirname}/../contracts/todo.js`);
23 | fibosClient.setcodeSync(config.contract.name, 0, 0, fibosClient.compileCode(jsCode));
24 |
25 | // getcode
26 | const code = fibosClient.getCodeSync(config.contract.name, true);
27 | console.log('code:', code);
28 |
29 | // setabi
30 | const abi = JSON.parse(fs.readTextFile(`${__dirname}/../contracts/todo.abi`));
31 | fibosClient.setabiSync(config.contract.name, abi);
32 |
--------------------------------------------------------------------------------
/scripts/server.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const Koa = require("koa");
3 | const bodyParser = require("koa-bodyparser");
4 | const serve = require("koa-static");
5 | const webpack = require("webpack");
6 | const devWare = require("koa-webpack");
7 |
8 | const config = require("./webpack.dev.js");
9 |
10 | const app = new Koa();
11 | const port = 4000;
12 | app
13 | .use(bodyParser())
14 | .use(serve(path.join(__dirname, "../dist")))
15 | .use(
16 | devWare({
17 | config,
18 | dev: { publicPath: "/dist/" } /*, hot:{}*/
19 | })
20 | )
21 |
22 | .listen(port, () => {
23 | console.log("Server Started http://localhost:" + port.toString());
24 | });
25 |
--------------------------------------------------------------------------------
/scripts/webpack.dev.js:
--------------------------------------------------------------------------------
1 | var path = require("path");
2 |
3 | module.exports = {
4 | entry: ["./dapp/index.js"],
5 | output: {
6 | path: path.join(__dirname, "../dist"),
7 | filename: "bundle.js"
8 | },
9 | mode: "development",
10 | module: {
11 | rules: [
12 | { test: /\.js|jsx$/, use: ["babel-loader"], exclude: /node_modules/ },
13 | { test: /\.css$/, loader: 'style-loader!css-loader'}
14 | ]
15 | }
16 | };
--------------------------------------------------------------------------------
/start_fibos/node.js:
--------------------------------------------------------------------------------
1 | var fibos = require('fibos');
2 |
3 | fibos.load("http", {
4 | "http-server-address": "0.0.0.0:8888",
5 | "access-control-allow-origin": "*"
6 | });
7 | fibos.load("chain", {
8 | "delete-all-blocks": true
9 | });
10 | fibos.load("net");
11 | fibos.load("chain_api");
12 | // fibos.load("history_api");
13 | fibos.load("producer", {
14 | 'producer-name': 'eosio',
15 | 'enable-stale-production': true
16 | });
17 | fibos.config_dir = "start_fibos/fibos_config_dir/";
18 | fibos.data_dir = "start_fibos/fibos_data_dir/";
19 | fibos.enableJSContract = true;
20 | fibos.start();
21 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | var FIBOS = require('fibos.js');
2 | var config = require('../config');
3 | var fs = require('fs');
4 | var test = require('test');
5 | test.setup();
6 |
7 | describe(`todo`, () => {
8 | var fibosClient;
9 | before(() => {
10 | fibosClient = FIBOS({
11 | chainId: config.client.chainId, // 32 byte (64 char) hex string
12 | keyProvider: config.client.keyProvider,
13 | httpEndpoint: config.client.httpEndpoint,
14 | logger: {
15 | log: null,
16 | error: null
17 | }
18 | });
19 | fibosClient.newaccountSync({
20 | creator: 'eosio',
21 | name: config.testContract.name,
22 | owner: config.account.publicKey,
23 | active: config.account.publicKey,
24 | });
25 | // setcode
26 | const jsCode = fs.readTextFile('../contracts/todo.js');
27 | fibosClient.setcodeSync(config.testContract.name, 0, 0, fibosClient.compileCode(jsCode));
28 |
29 | // setabi
30 | const abi = JSON.parse(fs.readTextFile('../contracts/todo.abi'));
31 | fibosClient.setabiSync(config.testContract.name, abi);
32 | });
33 | it(`insert data`, () => {
34 | var ctx = fibosClient.contractSync(config.testContract.name);
35 | ctx.emplacetodoSync(1,"say something",0, {
36 | authorization: config.testContract.name
37 | });
38 | console.notice('fibos.getTableRowsSync(true, config.testContract.name, user1, todos)',
39 | fibosClient.getTableRowsSync(true, config.testContract.name, config.testContract.sender, 'todos'));
40 | });
41 |
42 | it(`find data`, () => {
43 | var ctx = fibosClient.contractSync(config.testContract.name);
44 | ctx.findtodoSync(1,{
45 | authorization: config.testContract.name
46 | })
47 | console.notice('fibos.getTableRowsSync(true, config.testContract.name, user1, todos)',
48 | fibosClient.getTableRowsSync(true, config.testContract.name, config.testContract.sender, 'todos'));
49 | });
50 |
51 | it(`user modofy record`, () => {
52 | var ctx = fibosClient.contractSync(config.testContract.name);
53 | ctx.updatetodoSync(1,"done",1,{
54 | authorization: config.testContract.name
55 | })
56 | assert.isTrue(fibosClient.getTableRowsSync(true, config.testContract.name, config.testContract.sender, 'todos').rows.length === 1);
57 | });
58 |
59 | it(`user delete record`, () => {
60 | var ctx = fibosClient.contractSync(config.testContract.name);
61 | ctx.destorytodoSync(1,{
62 | authorization: config.testContract.name
63 | })
64 | assert.isTrue(fibosClient.getTableRowsSync(true, config.testContract.name, config.testContract.sender, 'todos').rows.length === 0);
65 | });
66 | })
67 |
68 | require.main === module && test.run(console.DEBUG);
69 |
70 |
--------------------------------------------------------------------------------