Lingkun's Small House

Youth is not a time of life, it is a state of mind.


  • Home

  • Archives

Configure WFDB from physionet in Ubuntu 16.04

Posted on 2018-10-10 | In Stream Processing

Configure WFDB from physionet in Ubuntu 16.04

Install prerequisites

1
apt-get install gcc libcurl4-openssl-dev libexpat1-dev

Download the current version of the WFDB software package

Download from https://physionet.org/physiotools/wfdb.tar.gz, then run

1
tar xfvz wfdb.tar.gz

Configure, install, and test the package

1
2
3
4
cd wfdb-10.x.y     ... here 10.x.y represents the version of wfdb in your PC
./configure
sudo make install ... intalled into /usr/local
make check

Install the WAVE on 64 bit Ubuntu

Basically, we first install 32-bit dependencies for the WAVE and then restore 64-bit dependencies in Ubuntu.

1
2
3
4
5
6
7
8
9
10
11
sudo -s
dpkg --add-architecture i386
apt-get remove libcurl4-openssl-dev:amd64
apt-get install xviewg-dev:i386 libcurl4-openssl-dev:i386 build-essential gcc-multilib
rm -f /etc/apt/sources.list.d/wfdb-tmp.list
./install-wave32 -q
apt-get remove libcurl4-openssl-dev:i386
apt-get install libcurl4-openssl-dev
apt-get install xfonts-100dpi
xset +fp /usr/share/fonts/X11/100dpi
xset fp rehash

Test using an example

Build a .c file named as psamples.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <wfdb/wfdb.h>

main()
{
int i;
WFDB_Sample v[2];
WFDB_Siginfo s[2];

if (isigopen("100s", s, 2) < 2)
exit(1);
for (i = 0; i < 10; i++) {
if (getvec(v) < 0)
break;
printf("%d\t%d\n", v[0], v[1]);
}
wfdbquit();
exit(0);
}

Compile it using following command:

1
gcc -o psamples psamples.c -lwfdb

Run it:

1
./psamples

Then you can view the outputs as below:

1
2
3
4
5
6
7
8
9
10
995     1011
995 1011
995 1011
995 1011
995 1011
995 1011
995 1011
995 1011
1000 1008
997 1008

References

  1. https://physionet.org/physiotools/wpg/wpg.htm#Top [WFDB Programmer’s Guide]
  2. https://physionet.org/physiotools/wfdb-linux-quick-start.shtml [WFDB quick start for GNU/Linux]
  3. https://physionet.org/physiotools/wave-installation.shtml [WAVE installation notes]

Using Python to Write a Printable Red-black Tree

Posted on 2018-05-28

引文

红黑树是计算机算法中非常经典的一种数据结构。

然而之前由于个人学习的疏忽,一直无缘了解什么是红黑树(当时学习了AVL树)。

如今,回过头来学习红黑树,深深感受到这个算法的美妙,并震惊于发明者的聪明才智。

已经有很多人就红黑树的算法进行了解释,此处不做过多赘述。这里,我简单的附上一个可以打印的红黑树的代码源码,供读者参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
class TreeNode(object):
def __init__(self, key, color=None, left=None, right=None, parent=None):
self.key = key
self.color = color # 0 for red, 1 for black
self.left = left
self.right = right
self.parent = parent

def __str__(self, depth=0):
ret = ""
# Print right branch
if self.right.key != -1:
ret += self.right.__str__(depth + 1)
# Print own value
if self.color == 0:
pcolor = 'r'
else:
pcolor = 'b'
ret += "\n" + (" "*depth) + str(self.key) + pcolor
# Print left branch
if self.left.key != -1:
ret += self.left.__str__(depth + 1)

return ret

class Tree(object):
def __init__(self):
self.nil = TreeNode(-1, 1)
self.root = self.nil

def leftRotate(T, x):
y = x.right
x.right = y.left
if y.left != T.nil:
y.left.parent = x
y.parent = x.parent
if x.parent == T.nil:
T.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y

def rightRotate(T, x):
y = x.left
x.left = y.right
if y.right != T.nil:
y.right.parent = x
y.parent = x.parent
if x.parent == T.nil:
T.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y

def rbInsert(T, z):
y = T.nil
x = T.root
while x != T.nil:
y = x
if z.key < x.key:
x = x.left
else:
x = x.right
z.parent = y
if y == T.nil:
T.root = z
else:
if z.key < y.key:
y.left = z
else:
y.right = z
z.left = z.right = T.nil
z.color = 0
rbInsertFix(T, z)

def rbInsertFix(T, z):
while z.parent.color == 0:
if z.parent == z.parent.parent.left:
y = z.parent.parent.right
if y.color == 0:
z.parent.color = 1
y.color = 1
z.parent.parent.color = 0
z = z.parent.parent
else:
if z == z.parent.right:
z = z.parent
leftRotate(T, z)
z.parent.color = 1
z.parent.parent.color = 0
rightRotate(T, z.parent.parent)
else:
y = z.parent.parent.left
if y.color == 0:
z.parent.color = 1
y.color = 1
z.parent.parent.color = 0
z = z.parent.parent
else:
if z == z.parent.left:
z = z.parent
rightRotate(T, z)
z.parent.color = 1
z.parent.parent.color = 0
leftRotate(T, z.parent.parent)

T.root.color = 1


def treeMin(T, x):
while x.left != T.nil:
x = x.left
return x


def treeMax(T, x):
while x.right != T.nil:
x = x.right
return x


def treeSuccessor(T, x):
if x.right != T.nil:
return treeMin(T, x.right)
y = x.parent
while y != T.nil and x == y.right:
x = y
y = x.parent
return y


def treePreSuccessor(T, x):
if x.left != T.nil:
return treeMax(T, x.left)
y = x.parent
while y != T.nil and x == y.left:
x = y
y = x.parent
return y

def rbDelete(T, z):
if z.left == T.nil or z.right == T.nil:
y = z
else:
y = treeSuccessor(T, z)
if y.left != T.nil:
x = y.left
else:
x = y.right
x.parent = y.parent
if y.parent == T.nil:
T.root = x
else:
if y == y.parent.left:
y.parent.left = x
else:
y.parent.right = x
if y != z:
z.key = y.key
if y.color == 1:
rbDeleteFix(T, x)
return y

def rbDeleteFix(T, x):
while x != T.root and x.color == 1:
if x == x.parent.left:
w = x.parent.right
if w.color == 0:
w.color = 1
x.parent.color = 0
leftRotate(T, x.parent)
w = x.parent.right
if w.left.color == 1 and w.right.color == 1:
w.color = 0
x = x.parent
else:
if w.right.color == 1:
w.left.color = 1
w.color = 0
rightRotate(T, w)
w = x.parent.right
w.color = x.parent.color
x.parent.color = 1
w.right.color = 1
leftRotate(T, x.parent)
x = T.root
else:
w = x.parent.left
if w.color == 0:
w.color = 1
x.parent.color = 0
rightRotate(T, x.parent)
w = x.parent.left
if w.right.color == 1 and w.left.color == 1:
w.color = 0
x = x.parent
else:
if w.left.color == 1:
w.right.color = 1
w.color = 0
leftRotate(T, w)
w = x.parent.left
w.color = x.parent.color
x.parent.color = 1
w.left.color = 1
rightRotate(T, x.parent)
x = T.root
x.color = 1

def main():
T = Tree()
rbInsert(T, TreeNode(11))
rbInsert(T, TreeNode(2))
rbInsert(T, TreeNode(14))
rbInsert(T, TreeNode(1))
# rbDelete(T, T.root)
rbInsert(T, TreeNode(7))
rbInsert(T, TreeNode(15))
rbInsert(T, TreeNode(5))
rbInsert(T, TreeNode(8))
rbInsert(T, TreeNode(4))
# rbInsert(T, TreeNode(7))
rbDelete(T, T.root.right.left)
print(T.root)


if __name__ == '__main__':
main()

'''
Output Example:
15r
14b
11r
8b
7b
5b
4r
2r
1b
'''

Project — Building a Simple Blockchain-based Crowdsensing System

Posted on 2018-04-11 | In Learn Solidity

Project — Building a Simple Blockchain-based Crowdsensing System

Author: Lingkun Kong, Linghe Kong, Please indicate the source for reproduction.

Abstract

Motivated by constructing a crowd-sensing system with security and low services fee, we propose building a blockchain-based crowd-sensing framework that replaces traditional triangle architecture by decentralized blockchain system. Also, in order to accelerate the formation of the fabric of trust, instead of releasing a new virtual currency, the proposed framework implements applications of smart contracts to reward sensing-task workers which offers reliable anonymity. Also, by leveraging blockchain technology in crowd-sensing, the proposed framework is also an exploration on the mining puzzles of proof-of-usefulness.

Background and Motivation

Crowd-sensing systems, which take advantage of pervasive mobile devices to efficiently collect data, have gained considerable interest and adoption in recent years [1][2]. However, the majority of existing crowd-sensing systems rely on central servers, which are subject to the weaknesses of the traditional trust-based model, such as single point of failure and privacy disclosure [3][4]. They are also vulnerable to distributed denial of service (DDoS) and Sybil attacks due to malicious users’ involvement [5]. In addition, high service fees charged by the crowd-sensing platform which has monopolized the market may stem the development of crowd-sensing. How to address these potential issues remains to be an open problem.

There have been several studies to deal with part of the aforementioned open problem [6-10], while the majority of these researches are built on the traditional triangular structure crowd-sensing models, which suffer from breakdown of trust. Thus, this research proposal is motivated by this: Can we design a decentralized crowd-sensing system with security and low services fee?

Introduction of Blockchain-based Crowd-sensing System

The past few years have witnessed the emergence of blockchain as well as its multiple applications [11,12,16,17,19,22], which provides us an opportunity to solve all of the above issues in crowd-sensing systems simultaneously. Therefore, I propose building a blockchain-based decentralized framework for crowd-sensing, with the purpose of alleviating privacy leakage and reducing the charge of the central platform.

To illustrate, by leveraging blockchain architecture, we can replace the centralized crowd-sensing platform by decentralized blockchain system. Therefore, the services fee charged by the platform can be used more efficiently, as it now is all paid to workers and blockchain miners [14]. Also, since now the crowd-sensing process does not depend on any central third party, there is no single point of failure issue. Besides, for the sake of properties of blockchain, we can guarantee privacy by allowing users to register without true identity and storing encrypted sensory data in the distributed database. Further, by stipulating that each identity must make a deposit before participation in smart contract protocols, we can efficiently prevent various attacks (e.g. DDoS, Sybil and “false-reporting” attacks [13]).

In the context of blockchain applications, current prevalent blockchain-based systems such as Bitcoin [11], Litecoin [16], and Zcash [17], etc., always issue virtual currencies to incentivize miners and try to convince both miners and users that the virtual currency is worthy of being hold. However, to earn the trust from users and maintain the fabric of trust are quite difficult. Also, legal problems always ensue the issue of virtual currencies, and Governments worry about the high anonymity within currency systems will found the breeding ground for the crime [18]. When dealing with crowd-sensing problems, it is unrealistic to quickly build the reputation of the system and win the trust from users by issuing new virtual currencies. Additionally, with the awareness of legal issues, it is impractical to universally apply systems which release the virtual currency.

Moreover, in traditional blockchain-based systems, there’s a concern that Bitcoin mining is extremely profligate, since massive energy is wasted by miners in solving “useless” puzzles for block discovery [21]. Thus, “Is there a puzzle, whose solution provides useful benefit to society, while still satisfying the basic requirements of Blockchain puzzles?” is raised to be a natural question. There have been several studies which attempted to reduce blockchain-based system’s energy waste, such as Primecoin and Permacoin [19,22]. However, their methods are not feasible for a lot of potential candidates such as problems of protein folding [23], space signal searching [20], which are of great scientific usefulness while needs a trusted administrator. In this case, building a blockchain-based crowd-sensing framework will also be an exploration of the proof-of-usefulness puzzle, which might be helpful to reduce the energy waste in traditional blockchain systems.

Faced with these challenges, in our proposed framework, we introduce applications of smart contracts to reward users, which should be first initiated by sensing-task requesters with certain reserve money. On the one hand, by this method, we can build the reputation of the framework and raise the enthusiasm of both miners and workers in a short time. On the other hand, since there is deposit in the smart contract, and the methods of getting rewards are substantiated by published smart contract, both requesters and workers can trust the immutable codes from published smart contract as a credible administrator. Therefore, the new framework will be feasible for broad implementation of proof-of-usefulness puzzles.

Specifically, the traditional crowd-sensing process consists of three groups of roles: requesters, workers and a centralized crowd-sensing system, where requesters submit tasks to the system and receive sensing results from the system; workers pull tasks from the system, complete tasks they interested in and submit sensing results to the system; the centralized system deals with submissions from requesters and workers and responds them accordingly. Figure below presents the crowd-sensing by traditional centralized systems.

In the blockchain-based decentralized system which we propose, there is no centralized platform in crowd-sensing process anymore. Instead, by leveraging blockchain techniques, the crowd-sensing process is managed by a decentralized system, which is presented in Figure below.

Basically, the crowd-sensing process can be divided into following steps:

Step1: Requesters post tasks, and, meanwhile, they need to initialize the examining rules and send to communication platform, which, in our design, actually is to publish a smart contract and then create the function in smart contract.

Step2: Workers, by querying blockchain and fetching message from communication platform, i.e., querying the published smart contract, obtain attractive sensing tasks. After finishing tasks by recording sensing data, they post the message to the communication platform, i.e., call specific functions in smart contracts.

Step3: By querying blockchain and listening to the communication platform, miners fetch unsubstantiated sensing data, and they can examine the quality of this data based on rules the requester establishes. After miners substantiate the quality of sensing data, they will get the reward after pushing processed sensing data into blocks. In general, miners obtain reward by contributing computing power for running smart contracts.

Step4: Requesters listen to the blockchain periodically. Once they are satisfied with sensed data or decide to not continue collecting data for other reasons, they can send message to the system to burn the blockchain and get the remained reserve money from smart contract. As this message will be broadcasted in the system, miners and workers will then cease to work.

Detailed Implementation of Smart Contract

Additionally, we propose to add applications of smart contracts over the whole framework with the purpose of quickly obtaining users’ trust and making the design feasible for various purposes, such as aforementioned problems of protein folding and aliens discovery. Figure below shows the structure of decentralized system after adding smart contracts.

In this figure, the number indicates the order of the operation in a certain crowd-sensing task, where operation 3* means this operation can be processed concurrently with operation 3, and operation mark x means this operation can be undertaken in any time after operation 2. Moreover, the solid lines in the figure stand for operations being necessarily done in a certain task, while the unfilled lines indicate these operations might not be properly processed.

In this system, the requester enters in the system and create the smart contract by setting requirements for sensing data and stores a certain amount of deposits for determining the rewards. After that, once workers are attracted by the rewards as well as their data are substantiated by miners, they can get rewards stored in the smart contract protocol right away. Therefore, the reputation of this system can be quickly built, and the enthusiasm of both miners and workers can be aroused as once they got works done, they can receive valuable rewards. Also, since rules are “printed” in the smart contract, both workers and miners can trust the published smart contract as a credible administrator. Therefore, the challenge of lacking trusted administrators for puzzles like protein folding and space signal searching is overcome in this proposed framework.

Remarks: The submission of collected data will cost workers certain amount of gas in smart contract. In fact, it is tantamount for workers to make security deposits before participation in crowd-sensing task, which efficiently prevents various attacks (e.g. DDoS, Sybil and “false-reporting” attacks [13]).

Using an Simple Example to Show How the System Works

Here, we use a simple wifi-sensing task to show how the system works.

First of all, we present the source code of smart contract of wifi-sensing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
pragma solidity ^0.4.21;

contract SensingWifi{
uint public rewardUnit;
uint public rewardNum;
uint public dataCount;
bytes32 public wifiName;
address public requester;
enum State {Uncreated, Created, Inactive}
State public state;

mapping(bytes32 => string) dataStatuses; // Either '' or 'Committed'

modifier condition(bool _condition) {
require(_condition);
_;
}

modifier onlyRequester() {
require(msg.sender == requester);
_;
}

modifier inState(State _state) {
require(state == _state);
_;
}

event Aborted();
event TaskInited(uint ru, uint rn, bytes32 wn);
event ViewTask(uint ru, uint rn, bytes32 wn, uint cnt);
event DataCommited(bytes32 l, bytes32 w, int s);
event TaskDone();
event dataCheck(uint cnt);

// Init the task as requster.
// The requster need to set the value of reward for each sensing data,
// as well as the maximum number of data he needed.
function initTask(uint _rewardUnit, uint _rewardNum, bytes32 _wifiName)
public
inState(State.Uncreated)
condition(msg.value >= _rewardUnit * _rewardNum)
payable
{
requester = msg.sender;
rewardUnit = _rewardUnit;
rewardNum = _rewardNum;
wifiName = _wifiName;
state = State.Created;
emit TaskInited(_rewardUnit, _rewardNum, _wifiName);
}

// Abort the Task and reclaim the ether,
// Can only be called by the requester.
function abort()
public
onlyRequester
inState(State.Created)
{
require(dataCount <= rewardNum);
state = State.Inactive;
requester.transfer(this.balance);
emit Aborted();
}

function getDataCnt()
public
onlyRequester
inState(State.Created)
{
emit dataCheck(dataCount);
}

// Worker answer the task by sending data
// such as {"41-24-12.2-N 2-10-26.5-E", "SJTU", -51}

function getTask()
public
inState(State.Created)
{
emit ViewTask(rewardUnit, rewardNum, wifiName, dataCount);
}

function commitTask(bytes32 _location, bytes32 _wifiName, int _signalDegree)
public
inState(State.Created)
{
require(dataCount < rewardNum);
bytes memory sensingDataCommit = bytes(dataStatuses[_location]);
// Requester wants to get data from different location
require(sensingDataCommit.length == 0);

// Make sure that the wifi signal sensed is what requester wants
require(wifiName==_wifiName);

// The theoretical maximum value of signal strength is -30 dBm
require(_signalDegree < -30);

dataStatuses[_location] = "Committed";

dataCount += 1;
if(dataCount == rewardNum){
state = State.Inactive;
requester.transfer(this.balance);
emit TaskDone();
}
msg.sender.transfer(rewardUnit);
emit DataCommited(_location, _wifiName, _signalDegree);
}
}

Functions for Requesters:

For requesters, they are the initiators of the wifi-sensing tasks. Therefore, they have responsibilities to write the smart contract and initiate the wifi-sensing task.

initTask(): Requesters can call the initTask() function to create a wifi-sensing task and determine the rewards for each processed sensing data. In this function, requesters need to save certain amount of deposits in the smart contract and specify the value of each reward as well as the maximum number of data required.

abort(): Requesters have the rights to abort the task once they believe they have collected enough data by viewing the number of data in getDataCnt(). This function will give requesters refunds of their deposits.

Also, we developed a simple interface for users to play the role as requesters, and figure below is the screenshot of the interface.

Here, users, playing as requesters, create a wifi-sensing task by setting Value of Each Reward as 100000000 wei, number of Data Required as 5 and wifi name as SJTU. Similarly, users can abort the task and check the current status of the task by click buttons of Abort and Check. The text beneath the title of Wifi Sensing — Requester will present corresponding information.

Functions for Workers:

For workers, they choose the tasks they are interested in and submit data for this tasks. Here we assume that workers are interested in the wifi-sensing task and try to work for it.

commitTask(): Workers call this function to submit their collected data. Before they submit their data, they need to watch carefully about the requirements of the data “enacted” by the requesters as they are writers of commitTask() function. Here, for example, requesters need the data of wifi signal which are collected from different places, named as SJTU and measured to be restricted in a conscionable range. To be noticed, if data submitted by the workers do not meet the requirements, workers cannot receive a single penny from their work but waste money in paying the transaction fee, i.e., gas to miniers. Therefore, workers need to be really careful when trying to submitting the data, and it is always a good idea for workers to call getTask() function first though a little amount of gas fee will be costed (about 0.00011 ETH ~ 0.05 USD in 04/11/2018).

We also provide a simple interface for workers to submit their data and get reward.

This figure is about the screenshot of worker interface after a worker clicking the View Task button.

This figure presents the screenshot of worker interface after a worker submits his data by clicking Commit button.

The interesting thing is that as in this example, the requester sets 100000000 wei (about 0.00000000001 ETH) as the value of each reward, which is much smaller than the costs of gas fee the worker pay for calling commitTask() and getTask() function (about 0.00046 ETH). Therefore, the worker fells into the trap set by the requester — the worker works for requester and loses money. In other words, the worker actually needs to be really careful when calling getTask() to view the reward of each data, since he can only earn money as long as the reward of each collected data is larger than transaction fees paid to hidden miniers (in this case, the reward should be larger than 0.00046 ETH).

Remarks for Miners: The miners are hidden behind the smart contract, and they earn money by contributing their computing power to run the complied program in smart contracts. Actually, both requesters and workers pay for miners by providing gas fee.

The source code of smart contract as well as the interfaces has been published on the webpage: https://github.com/Ohyoukillkenny/BCS

Analysis of the Blockchain-based Crowd-sensing System

In this part, we briefly analyze our blockchain-based crowd-sensing system from the aspects of security and the financial efficiency.

Security:

  1. By implementing smart contracts, the anomynity of workers as well as requesters can be highly assured, since they only know the ETH accounts of each others. Also, for workers, if they believe their collected data may include several private information which make them uncomfortable to share, they can directly refuse to submit the data.
  2. As we have mentioned in the Remark of Introduction of Blockchain-based Crowd-sensing System, workers actually need to make security deposits, i.e., pay transaction fees to miners, before participation in crowd-sensing task, which efficiently prevents various attacks (e.g. DDoS, Sybil and “false-reporting” attacks [13]).
  3. One potential attack of our system is so called front-run attacking, which has been leveraged in attacking Bancor protocol [27]. In our schema, attackers can use front-run attacking to steal the rewards which are supposed to provide to workers. To illustrate, attackers always listen to the network , fetch the submitted data from workers and then submit these data immediately. Since many crowd-sensing tasks require the uniqueness of the data and the attacker has chances to get submitted data substantiated by miners earlier, the “real” worker might not be able to get his reward as expected. However, there has been several solutions which we can refered to avoid this attack, even in the article [27] which discovered the front-run attacking toward applications of smart contracts. In fact, in our system, we can simply spread rumors among the networks to prevent this attack. That is we can submit a lot of invalid data to the smart contract while not confirm it, otherwise we will waste transaction fee. When attackers fetch these rumor message, they, however, will directly submit this message and waste a large bunch of money. Therefore, the attacking will be stemed.

Financial Efficiency:

The minimum cost of requesters for each data largely depends on the cost of transaction fee workers need to pay. This is because if the reward for each data cannot cover the transaction fee workers need to pay for submitting the data, no one will be willing to work for the requester.

Therefore, using the wifi-sensing task as an instance, we use the table below to briefly count the average cost of transaction fees workers need to pay by lauching experiments of the participation of 1000 workers.

Cost of getTask() Call Cost of commitTask() Call Size of the Data avg Total Cost
0.00011 ETH 0.00041 ETH 97.8 bytes 0.00052 ETH

Due to the violent fluctuation of the price of ETH, it is hard to evaluate the value of 0.00052 ETH in real-world market. Here we use the exchange rate between USD and ETH in 04/11/2018 [28] to roughly estimate the the value of 0.00052 ETH as 0.217 USD, which means that requesters need to pay each wifi-sensing data for at least 0.217 USD.

This value might be too high for a simple wifi-sensing task. However, when the data the requester attempts to collect are essentially sensitive and require high anonymity, e.g., personal income, medical history and etc., this price might be totally acceptable. After all, the key advantage of decentralized crowdsensing system is to break the control of centralized data manage system as well as the monopoly price of data-sensing task. We hope our blockchain-based crowd-sensing system can offer users an another option when try to participate in crowd-sensing tasks.

Conclusion

To sum up, in this article, we propose building a blockchain-based crowd-sensing to make up for the paucity of decentralized crowd-sensing systems with security and low services fee. Since we are still in the early stage of blockchain technology, this project will be of importance to research in distributed systems by providing a concrete blockchain-based solution for a known scientific problem, i.e., crowd-sensing management.

Reference

[1] Ma, H., Zhao,D., & Yuan, P. (2014). Opportunities in mobile crowd sensing. IEEECommunications Magazine, 52(8), 29-35.

[2] Zhang, X.,Yang, Z., Sun, W., Liu, Y., Tang, S., Xing, K., & Mao, X. (2016).Incentives for mobile crowd sensing: A survey. IEEE Communications Surveys& Tutorials, 18(1), 54-67.

[3]Vergara-Laurens, I. J., Jaimes, L. G., & Labrador, M. A. (2016).Privacy-preserving mechanisms for crowdsensing: Survey and researchchallenges. IEEE Internet of Things Journal.

[4] Pournajaf, L.,Xiong, L., Garcia-Ulloa, D. A., & Sunderam, V. (2014). A survey on privacyin mobile crowd sensing task management. Tech. Rep. TR-2014–002.

[5] Krontiris, I.,Langheinrich, M., & Shilton, K. (2014). Trust and privacy in mobileexperience sharing: future challenges and avenues for research. IEEECommunications Magazine, 52(8), 50-55.

[6] Cardone, G.,Foschini, L., Bellavista, P., Corradi, A., Borcea, C., Talasila, M., &Curtmola, R. (2013). Fostering participaction in smart cities: a geo-socialcrowdsensing platform. IEEE Communications Magazine, 51(6), 112-119.

[7] Cardone, G.,Cirri, A., Corradi, A., & Foschini, L. (2014). The participact mobile crowdsensing living lab: The testbed for smart cities. IEEE CommunicationsMagazine, 52(10), 78-85.

[8] Hamm, J.,Champion, A. C., Chen, G., Belkin, M., & Xuan, D. (2015, June). Crowd-ML: Aprivacy-preserving learning framework for a crowd of smart devices.In Distributed Computing Systems (ICDCS), 2015 IEEE 35th InternationalConference on (pp. 11-20). IEEE.

[9] Jayarajah, K.,Balan, R. K., Radhakrishnan, M., Misra, A., & Lee, Y. (2016, June).LiveLabs: Building In-Situ Mobile Sensing & Behavioural ExperimentationTestBeds. In Proceedings of the 14th Annual International Conference onMobile Systems, Applications, and Services (pp. 1-15). ACM.

[10] Han, G., Liu,L., Chan, S., Yu, R., & Yang, Y. (2017). HySense: A Hybrid MobileCrowdSensing Framework for Sensing Opportunities Compensation under DynamicCoverage Constraint. IEEE Communications Magazine, 55(3), 93-99.

[11] Nakamoto, S.(2015). Bitcoin: A Peer-to-Peer Electronic Cash System. November 2008.

[12] Swan, M.(2015). Blockchain: Blueprint for a new economy. “ O’Reilly Media,Inc.”.

[13] Zhang, X.,Xue, G., Yu, R., Yang, D., & Tang, J. (2015). Keep your promise: Mechanismdesign against free-riding and false-reporting in crowdsourcing. IEEEInternet of Things Journal, 2(6), 562-572.

[14] Li, M., Lu,W., Weng, J., & Yang, A. (2017). CrowdBC: A Blockchain-based Decentralized Framework for Crowdsourcing. IACR Cryptology ePrint Archive, 2017, 444.

[15] https://en.wikipedia.org/wiki/PayPal

[16] Greenberg, A.(2016). Zcash, an untraceable bitcoin alternative, launches in alpha.

[17] Lee, C.(2011). Litecoin.

[18]http://www.gov.cn/gzdt/2013-12/05/content_2542751.htm

[19] King, S.(2013). Primecoin: Cryptocurrency with prime number proof-of-work. July7th.

[20] https://setiathome.berkeley.edu/

[21] https://motherboard.vice.com/en_us/article/aek3za/bitcoin-could-consume-as-much-electricity-as-denmark-by-2020

[22] Miller, A.,Juels, A., Shi, E., Parno, B., & Katz, J. (2014, May). Permacoin:Repurposing bitcoin work for data preservation. In Security and Privacy(SP), 2014 IEEE Symposium on (pp. 475-490). IEEE.

[23] Dill, K. A.,& MacCallum, J. L. (2012). The protein-folding problem, 50 yearson. science, 338(6110), 1042-1046.

[24] Ron Rivest, Leonard Adleman, and Michael L. Dertouzos. On data banks and privacy homomorphisms. Foundations of Secure Computation, 1978.

[25] Craig Gentry. Fully homomorphic encryption using ideal lattices. STOC, 2009.

[26] Jake Loftus, Alexander May, Nigel P. Smart, and Frederik Vercauteren. On CCA-Secure Fully Homomorphic Encryption. Cryptology ePrint Archive 2010/560.

[27] https://hackernoon.com/front-running-bancor-in-150-lines-of-python-with-ethereum-api-d5e2bfd0d798

[28] https://coinmarketcap.com/

How to find the Mr. Right

Posted on 2018-04-02 | In Algorithms

How to find the Mr. Right

作者:孔令坤,转载请注明出处

青春苦短,一个女性的青春假设为18到28岁,在10年期间内每半年假设可以找到一个男友,那么在这20次尝试的过程中应当采取怎样的策略才能从理论上找到Mr. Right呢?

前提条件

  1. 好马不吃回头草,优秀的妹子才不和前任继续往来。
  2. 每找到一个新的男友后,妹子可以根据其综合表现进行评分。

策略

假设尝试次数为n,妹子们可以在找完k个男友后,抛弃掉他们,然后选取这k个人中最高的综合评分,记为bestScore。

在之后的找男友大作战中,只要有人的综合评分大于bestScore,妹子就可以赶紧选择他。

接下来,我们需要从概率学的角度来计算,k取何值时,妹子可以在第k+1次选取中最大概率地选到n次尝试机会里分数最高的男友,即在k+1次时找到人群中最优秀的男友。

算法

1
2
3
4
5
6
7
8
9
10
# this function returns the index of the MrRight when having n shots
def findMrRight(k,n):
bestScore = -1
for i in range(k):
if score(i) > bestScore:
bestScore = score(i)
for i in range(k,n):
if score(i) > bestScore:
return i
return n

概率分析

记$S$为妹子成功的选择到了Mr. Right的事件,$S_i$表示Mr. Right是第\$i\$个男友时成功的事件,即$k<i\leq n$时妹子找到了Mr. Right。由于不同的$S_i$不相交,于是我们有:
$$
\text{Pr}(S) = \sum_{i=k+1}^{n}\text{Pr}(S_i)
$$
接下来我们来计算$\text{Pr}(S_i)$。为了使在第$i$个男友时找到Mr. Right,有两件事情必须发生:

  1. Mr. Right必须在第$i$次被找到,即所有$n$个男性中分数最高的男性在妹子的第$i$次尝试中被发现——记此事件为$A_i$。
  2. 妹子不能选择在第$k+1$到第$i-1$次尝试中的男友,即在第1次到第$i-1$次尝试中,综合评分最高的男友需要出现在前$k$次中——记此事件为$B_i$。

对于事件$A_i$,其相当于$n$个男性中分数最高的男性落在了第$i$个位置上,概率有$\text{Pr}(A_i)=\frac{1}{n}$。

对于事件$B_i$,其相当于$i-1$个男性中分数最高的男性落在了位置$1,2,…,k-1,k$中的某个位置,概率满足$\text{Pr}(B_i)=\frac{k}{i-1}$。

由于事件$A_i$、事件$B_i$相互独立,我们发现:
$$
\begin{align}
\text{Pr}(S) & = \sum_{i=k+1}^{n}\text{Pr}(S_i) = \sum_{i=k+1}^{n}\text{Pr}(A_i \cap B_i) \
&=\sum_{i=k+1}^{n}\text{Pr}(A_i) \text{Pr}(B_i)\
&=\sum_{i=k+1}^{n}\frac{k}{n(i-1)}\
&=\frac{k}{n}\sum_{i=k}^{n-1}\frac{1}{i}\
\end{align}
$$
根据放缩公式,我们可以得到:
$$
\int_{k}^{n}\frac{1}{x}\mathbf{d}x \le \frac{k}{n}\sum_{i=k}^{n-1}\frac{1}{i} \le \int_{k-1}^{n-1}\frac{1}{x}\mathbf{d}x.
$$
从而,我们解这个定积分,可以得到:
$$
\frac{k}{n}(\mathbf{ln}n - \mathbf{ln}k) \le \text{Pr}(S) \le \frac{k}{n}(\mathbf{ln}(n-1) - \mathbf{ln}(k-1)).
$$
其中,等式左边为妹子在第$i$个男友时找到Mr. Right的概率的下界。由于我们希望最大化成功的概率,我们希望能够最大化这个下界。因此,我们将下界表达式$\frac{k}{n}(\mathbf{ln}n - \mathbf{ln}k)$对$k$求导,得:
$$
\frac{1}{n}(\mathbf{ln}n - \mathbf{ln}k -1)
$$
在对$k$导函数单调递减的情况下,令此导数等于0,我们可以得到:
$$
\begin{align}
&\mathbf{ln}k = \mathbf{ln}n -1 = \mathbf{ln}\frac{n}{e}\
\Leftrightarrow \text{ } &k=\frac{n}{e},
\end{align}
$$
即当$k=\frac{n}{e}$时,概率的下界最大化为$\frac{1}{e}$。换句话说,假如一共可以尝试去和$n$个男性交往,妹子们可以选择交往过$k=\frac{n}{e}$男友来积累经验,然后遇到更好的人就从了。因为这样,妹子们有最大的几率——超过$\frac{1}{e}$会找到人群中最优质的男性。

以之前所说的20个理论中交男友的机会为例,妹子们可以先通过之前的$\frac{20}{e} \approx 7$ 个男友来积攒经验,并在之后如果遇到比前七个男友都优秀的男性就从了,将会有高于$36.7\%$的几率找到属于自己的Mr. Right.

以上皆为扯淡之谈。

Web3-Solidity

Posted on 2018-03-27 | In Learn Solidity

Solidity学习笔记(5) — 使用Web3.js实现与Smart Contract的交互

作者:孔令坤,转载请注明出处

Web3官方API:https://github.com/ethereum/wiki/wiki/JavaScript-API

Youtube环境搭配视频:https://coursetro.com/courses/20/Developing-Ethereum-Smart-Contracts-for-Beginners

在本文中,我写了一个很简单的存取钱的智能合约,并借助web3.js提供的接口写了一个非常简单 的网页,来实现用户通过网页与smart contract的交互。

1.环境配置

首先,用户需要在google chrome中配置MetaMask。

之后,用户需要安装web3.js,具体安装方式见官方安装文档。

接下来,为了能在本地端实现web3.js与metamask中的账号以及smart contract的交互,我们需要在本地为网页文件创造一个虚拟的服务器环境。这里,我们使用lite-server来帮助我们实现这个需求。具体安装方法如下:

  1. 在装好web.js的文件夹目录下输入command line code:
1
>> npm install lite-server --save-dev

如果用户之前是全局安装web.js的话,需要先输入npm init。

  1. 打开目录中的 package.json文件,在其中的scripts中添加:
1
2
3
"scripts": {    
"dev": "lite-server"
},
  1. 在目录中已有index.html文件的前提下,输入如下语句即可正常运行网页中的js脚本:
1
>> npm run dev

可能这里我讲得有点粗糙,但是不用担心。有人已经在youtube上提供了非常详细的安装流程,见Youtube环境搭配视频。

2.smart contract开发

如果大家已经看过了我之前的博客,相信这一部分对于大家而言将不存在任何理解上的困难。

所以这里我简单的直接放上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
pragma solidity ^0.4.21;

contract SaveMoney{
address public user;
string public userName;
uint public deposits;

enum State {Unoccupied, Occupied}
State public state;

event accountInited(uint m, string name);
event moneyWithdrawed();

modifier condition(bool _condition) {
require(_condition);
_;
}

modifier onlyUser() {
require(msg.sender == user);
_;
}

modifier inState(State _state) {
require(state == _state);
_;
}
// initiate an account
function initAccount(uint _money, string _userName)
public
inState(State.Unoccupied)
condition(msg.value > _money) // since initiation costs some gas
payable
{
user = msg.sender;
userName = _userName;
deposits = _money;
state = State.Occupied;
user.transfer(this.balance);
emit accountInited(_money, _userName);
}
// withdraw the money from the contract
function withDraw()
public
inState(State.Occupied)
onlyUser
{
deposits = 0;
user.transfer(this.balance);
state = State.Unoccupied;
emit moneyWithdrawed();
}
}

3.网页开发与js脚本编写

首先,我放出网页的主体框架与css文件,其中大量借鉴了Developing-Ethereum-Smart-Contracts-for-Beginners中的框架。整体比较粗糙,但是非常便于大家理解代码。

main.css文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
body {
background-color:#F0F0F0;
padding: 2em;
font-family: 'Raleway','Source Sans Pro', 'Arial';
}
.container {
width: 50%;
margin: 0 auto;
}
label {
display:block;
margin-bottom:10px;
}
input {
padding:10px;
width: 50%;
margin-bottom: 1em;
}
button {
margin: 2em 0;
padding: 1em 4em;
display:block;
}

#instructor {
padding:1em;
background-color:#fff;
margin: 1em 0;
}

#loader {
width: 100px;
display:none;
}

index.html框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>

<link rel="stylesheet" type="text/css" href="main.css">

<script src="./node_modules/web3/dist/web3.min.js"></script>

</head>
<body>
<div class="container">

<h1>Money Bank</h1>

<h2 id="User"></h2>
<span id="userTrans"></span>
<hr>

<img id="loader" src="https://loading.io/spinners/double-ring/lg.double-ring-spinner.gif">

<label for="userName" class="col-lg-2 control-label">Name</label>
<input id="userName" type="text">

<label for="money" class="col-lg-2 control-label"># of Money</label>
<input id="money" type="text">

<button id="button1">Save Money</button>
<button id="button2">Withdraw</button>
</div>

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script>
// Put Scripts Here...
</script>

</body>
</html>

下面,我将分布挑重点来介绍一下我的js代码。

首先,我们在代码中放入:

1
2
3
4
5
6
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

这一段是官方提供的初始化连接web3的代码。如果你使用了metamask,那么currentProvider就会是来自你的metamask的网络以及账号。这个时候,在remix上,你的smart contract创建方式应当选择Injected Web3。

若你没有使用metamask,那么你可以在remix上使用Web3 Provider的方式来创建smart contract。这里"http://localhost:8545"其实来自另一个好用的eth smart contract开发应用,其安装方式如下:

1
>> npm install -g ethereumjs-testrpc

通过>> testrpc来启动这个provider并通过"http://localhost:8545"来进行数据的发送。

接下来,我们选择web3应用中的账户。

1
web3.eth.defaultAccount = web3.eth.accounts[0];

接下来,我们建立网页与合约之间的直接关联:

1
2
var saveMoney = web3.eth.contract(ABI OF THE CONTRACT);
var saveMoneyContract = saveMoney.at('ADDR OF THE CONTRACT');

ABI即smart contract编译后产生的一个文件,在remix中点击Start to compile按钮,然后点击Details按钮,即可复制smart contract的ABI,大致格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[
{
"constant": false,
"inputs": [],
"name": "withDraw",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "deposits",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
......
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "m",
"type": "uint256"
},
{
"indexed": false,
"name": "name",
"type": "string"
}
],
"name": "accountInited",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "moneyWithdrawed",
"type": "event"
}
]

然后smart contract的address的获取就比较简单了,就是创建好smart contract后,copy地址即可,e.g. 0x8f7e0a306b1a1f1205fa47b2bf2fefabaf056dae。

之后,设置点击save money和 withdraw按钮的触发事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$("#button1").click(function() {
$("#loader").show();
saveMoneyContract.initAccount($("#money").val(), $("#userName").val(), {value: $("#money").val()+100000} ,(err, res) => {
if (err) {
$("#loader").hide();
}
});
});

$("#button2").click(function() {
$("#loader").show();
saveMoneyContract.withDraw((err, res) => {
if (err) {
$("#loader").hide();
}
});
});

其中需要注意的是initAccount函数中参数的设定。由于这个函数是一个带value的payable的函数,我们需要在编程时不仅传递函数的参数,还得传递一定数量的以太币。在查阅了官方的api文件后,可以用如上的方式传递value,即

1
function(param1, param2, ..., paramk, {value: # of eth})

这里我在设置value时使用了$("#money").val()+100000,这是因为提交函数需要消耗一定量的gas,+100000wei是为了防止由于gas的消耗,用户无法在账户中存入数量为$("#money").val()的金额,导致交易失败。

最后,我们通过监听smart contract中的event来在网页上输出数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var saveEvent = saveMoneyContract.accountInited({}, 'latest');

saveEvent.watch(function(error, result){
if (!error){
$("#loader").hide();
$("#userTrans").html('Block hash: ' + result.blockHash);
console.log(result);
$("#User").html(result.args.name +' saved ' + result.args.m.c + ' wei.');
} else {
$("#loader").hide();
console.log(error);
}
});

var withDrawEvent = saveMoneyContract.moneyWithdrawed({}, 'latest');

withDrawEvent.watch(function(err, res){
if (!err){
$("#loader").hide();
$("#userTrans").html('Block hash: ' + res.blockHash);
$("#User").html('Money has been withdrawed!');
} else {
$("#loader").hide();
console.log(err);
}
});

最后,我附上了index.html文件的完整代码,供大家参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>

<link rel="stylesheet" type="text/css" href="main.css">

<script src="./node_modules/web3/dist/web3.min.js"></script>

</head>
<body>
<div class="container">

<h1>Money Bank</h1>

<h2 id="User"></h2>
<span id="userTrans"></span>
<hr>

<img id="loader" src="https://loading.io/spinners/double-ring/lg.double-ring-spinner.gif">

<label for="userName" class="col-lg-2 control-label">Name</label>
<input id="userName" type="text">

<label for="money" class="col-lg-2 control-label"># of Money</label>
<input id="money" type="text">

<button id="button1">Save Money</button>
<button id="button2">Withdraw</button>
</div>

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>

<script>
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

web3.eth.defaultAccount = web3.eth.accounts[0];

var saveMoney = web3.eth.contract([
{
"constant": false,
"inputs": [],
"name": "withDraw",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "deposits",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "user",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "userName",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "state",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_money",
"type": "uint256"
},
{
"name": "_userName",
"type": "string"
}
],
"name": "initAccount",
"outputs": [],
"payable": true,
"stateMutability": "payable",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "m",
"type": "uint256"
},
{
"indexed": false,
"name": "name",
"type": "string"
}
],
"name": "accountInited",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "moneyWithdrawed",
"type": "event"
}
]);
var saveMoneyContract = saveMoney.at('0x8f7e0a306b1a1f1205fa47b2bf2fefabaf056dae');
console.log(saveMoneyContract);

var saveEvent = saveMoneyContract.accountInited({}, 'latest');

saveEvent.watch(function(error, result){
if (!error){
$("#loader").hide();
$("#userTrans").html('Block hash: ' + result.blockHash);
console.log(result);
$("#User").html(result.args.name +' saved ' + result.args.m.c + ' wei.');
} else {
$("#loader").hide();
console.log(error);
}
});


var withDrawEvent = saveMoneyContract.moneyWithdrawed({}, 'latest');

withDrawEvent.watch(function(err, res){
if (!err){
$("#loader").hide();
$("#userTrans").html('Block hash: ' + res.blockHash);
$("#User").html('Money has been withdrawed!');
} else {
$("#loader").hide();
console.log(err);
}
});

$("#button1").click(function() {
$("#loader").show();
saveMoneyContract.initAccount($("#money").val(), $("#userName").val(), {value: $("#money").val()+100000} ,(err, res) => {
if (err) {
$("#loader").hide();
}
});
});


$("#button2").click(function() {
$("#loader").show();
saveMoneyContract.withDraw((err, res) => {
if (err) {
$("#loader").hide();
}
});
});

</script>

</body>
</html>
12…4

Lingkun Kong

17 posts
4 categories
4 tags
© 2018 Lingkun Kong
Powered by Hexo v3.7.1
|
Theme — NexT.Muse v6.1.0