Commit 878799ee authored by vipwzw's avatar vipwzw Committed by 33cn

fix game bug

parent 150cc47b
...@@ -32,11 +32,14 @@ Table.prototype.joinkey = function(left, right) { ...@@ -32,11 +32,14 @@ Table.prototype.joinkey = function(left, right) {
} }
Table.prototype.get = function(key, row) { Table.prototype.get = function(key, row) {
if (!isstring(row)) {
row = tojson(row)
}
return table_get(this.id, key, row) return table_get(this.id, key, row)
} }
Table.prototype.query = function(indexName, prefix, primaryKey, count, direction) { function query_list(indexName, prefix, primaryKey, count, direction) {
if (!count) { if (count !== 0 && !count) {
count = 20 count = 20
} }
if (!direction) { if (!direction) {
...@@ -52,7 +55,14 @@ Table.prototype.query = function(indexName, prefix, primaryKey, count, direction ...@@ -52,7 +55,14 @@ Table.prototype.query = function(indexName, prefix, primaryKey, count, direction
indexName = "" indexName = ""
} }
var q = table_query(this.id, indexName, prefix, primaryKey, count, direction) var q = table_query(this.id, indexName, prefix, primaryKey, count, direction)
return tojson(q) if (q.err) {
return null
}
return q
}
Table.prototype.query = function(indexName, prefix, primaryKey, count, direction) {
return query_list.call(this, indexName, prefix, primaryKey, count, direction)
} }
Table.prototype.replace = function(obj) { Table.prototype.replace = function(obj) {
...@@ -109,12 +119,31 @@ function print(obj) { ...@@ -109,12 +119,31 @@ function print(obj) {
JoinTable.prototype.save = function() { JoinTable.prototype.save = function() {
var ret = table_save(this.id) var ret = table_save(this.id)
print(ret)
if (this.kvc) { if (this.kvc) {
this.kvc.save(ret) this.kvc.save(ret)
} }
return ret return ret
} }
JoinTable.prototype.get = function(key, row) {
if (!isstring(row)) {
row = tojson(row)
}
return table_get(this.id, key, row)
}
JoinTable.prototype.query = function(indexName, prefix, primaryKey, count, direction) {
return query_list.call(this, indexName, prefix, primaryKey, count, direction)
}
function querytojson(data) {
if (!data) {
return "[]"
}
return tojson(data)
}
JoinTable.prototype.close = function() { JoinTable.prototype.close = function() {
table_close(this.lefttable.id) table_close(this.lefttable.id)
table_close(this.righttable.id) table_close(this.righttable.id)
...@@ -424,6 +453,10 @@ function Query(context) { ...@@ -424,6 +453,10 @@ function Query(context) {
} }
} }
Query.prototype.JoinKey = function(args) {
return table_joinkey(args.left, args.right).value
}
function throwerr(err) { function throwerr(err) {
if (err) { if (err) {
throw new Error(err) throw new Error(err)
...@@ -550,17 +583,22 @@ Exec.prototype.Guess = function(args) { ...@@ -550,17 +583,22 @@ Exec.prototype.Guess = function(args) {
match.id = this.txID() match.id = this.txID()
match.addr = this.context.from match.addr = this.context.from
match.hash = this.context.txhash match.hash = this.context.txhash
match.num = args.num
var game = this.kvc.get(match.gameid) var game = this.kvc.get(match.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("guess: game id not found")
} }
if (game.status != 1) { if (game.status != 1) {
throwerr("game status not open") throwerr("guess: game status not open")
}
if (this.context.from == game.addr) {
throwerr("guess: game addr and match addr is same")
} }
if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) { if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) {
throwerr("match bet litte than 1 or big than game.bet/10") throwerr("match bet litte than 1 or big than game.bet/10")
} }
var err = this.acc.execFrozen(this.name, this.context.from, game.bet) var err = this.acc.execFrozen(this.name, this.context.from, match.bet)
console.log(this.name, this.context.from, err)
throwerr(err) throwerr(err)
this.kvc.add(match.id, match) this.kvc.add(match.id, match)
this.kvc.addlog(match) this.kvc.addlog(match)
...@@ -568,18 +606,21 @@ Exec.prototype.Guess = function(args) { ...@@ -568,18 +606,21 @@ Exec.prototype.Guess = function(args) {
} }
Exec.prototype.CloseGame = function(args) { Exec.prototype.CloseGame = function(args) {
var local = new MatchLocalTable(this.kvc) var local = MatchLocalTable(this.kvc)
var game = this.kvc.get(args.id) var game = this.kvc.get(args.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("game id not found")
} }
var matches = local.getmath(args.id) var querykey = local.get("gameid", args)
print("---------")
print(querykey)
var matches = local.query("gameid", querykey, "", 0, 1)
if (!matches) { if (!matches) {
matches = [] matches = []
} }
var n = -1 var n = -1
for (var i = 0; i < RAND_MAX; i ++) { for (var i = 0; i < RAND_MAX; i++) {
if (sha256(args.randstr + i) == game.randhash) { if (Sha256(args.randstr + i) == game.randhash) {
n = i n = i
} }
} }
...@@ -588,7 +629,7 @@ Exec.prototype.CloseGame = function(args) { ...@@ -588,7 +629,7 @@ Exec.prototype.CloseGame = function(args) {
} }
//必须可以让用户可以有一个区块的竞猜时间 //必须可以让用户可以有一个区块的竞猜时间
if (this.context.height - game.height < MIN_WAIT_BLOCK) { if (this.context.height - game.height < MIN_WAIT_BLOCK) {
throwerr("close game must wait 2 block") throwerr("close game must wait "+MIN_WAIT_BLOCK+" block")
} }
for (var i = 0; i < matches.length; i++) { for (var i = 0; i < matches.length; i++) {
var match = matches[i] var match = matches[i]
...@@ -661,27 +702,22 @@ Exec.prototype.ForceCloseGame = function(args) { ...@@ -661,27 +702,22 @@ Exec.prototype.ForceCloseGame = function(args) {
} }
ExecLocal.prototype.NewGame = function(args) { ExecLocal.prototype.NewGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.Guess = function(args) { ExecLocal.prototype.Guess = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.CloseGame = function(args) { ExecLocal.prototype.CloseGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.ForceCloseGame = function(args) { ExecLocal.prototype.ForceCloseGame = function(args) {
return localprocess.call(this, args)
}
function localprocess(args) {
var local = MatchGameTable(this.kvc) var local = MatchGameTable(this.kvc)
local.addlogs(this.logs) local.addlogs(this.logs)
local.save() local.save()
...@@ -690,16 +726,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) { ...@@ -690,16 +726,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) {
Query.prototype.ListGameByAddr = function(args) { Query.prototype.ListGameByAddr = function(args) {
var local = GameLocalTable(this.kvc) var local = GameLocalTable(this.kvc)
return local.query("addr", args.addr, args.primaryKey, args.count, args.direction) var q = local.query("addr", args.addr, args.primaryKey, args.count, args.direction)
return querytojson(q)
} }
/* Query.prototype.ListMatchByAddr = function(args) {
game ->(1 : n) match var local = MatchGameTable(this.kvc)
game.gameid -> primary var q= local.query("addr#status", args["addr#status"], args.primaryKey, args.count, args.direction)
return querytojson(q)
}
match.gameid -> fk
match.id -> primary
*/
function GameLocalTable(kvc) { function GameLocalTable(kvc) {
this.config = { this.config = {
"#tablename" : "game", "#tablename" : "game",
......
...@@ -84,17 +84,22 @@ Exec.prototype.Guess = function(args) { ...@@ -84,17 +84,22 @@ Exec.prototype.Guess = function(args) {
match.id = this.txID() match.id = this.txID()
match.addr = this.context.from match.addr = this.context.from
match.hash = this.context.txhash match.hash = this.context.txhash
match.num = args.num
var game = this.kvc.get(match.gameid) var game = this.kvc.get(match.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("guess: game id not found")
} }
if (game.status != 1) { if (game.status != 1) {
throwerr("game status not open") throwerr("guess: game status not open")
}
if (this.context.from == game.addr) {
throwerr("guess: game addr and match addr is same")
} }
if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) { if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) {
throwerr("match bet litte than 1 or big than game.bet/10") throwerr("match bet litte than 1 or big than game.bet/10")
} }
var err = this.acc.execFrozen(this.name, this.context.from, game.bet) var err = this.acc.execFrozen(this.name, this.context.from, match.bet)
console.log(this.name, this.context.from, err)
throwerr(err) throwerr(err)
this.kvc.add(match.id, match) this.kvc.add(match.id, match)
this.kvc.addlog(match) this.kvc.addlog(match)
...@@ -102,18 +107,21 @@ Exec.prototype.Guess = function(args) { ...@@ -102,18 +107,21 @@ Exec.prototype.Guess = function(args) {
} }
Exec.prototype.CloseGame = function(args) { Exec.prototype.CloseGame = function(args) {
var local = new MatchLocalTable(this.kvc) var local = MatchLocalTable(this.kvc)
var game = this.kvc.get(args.id) var game = this.kvc.get(args.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("game id not found")
} }
var matches = local.getmath(args.id) var querykey = local.get("gameid", args)
print("---------")
print(querykey)
var matches = local.query("gameid", querykey, "", 0, 1)
if (!matches) { if (!matches) {
matches = [] matches = []
} }
var n = -1 var n = -1
for (var i = 0; i < RAND_MAX; i ++) { for (var i = 0; i < RAND_MAX; i++) {
if (sha256(args.randstr + i) == game.randhash) { if (Sha256(args.randstr + i) == game.randhash) {
n = i n = i
} }
} }
...@@ -122,7 +130,7 @@ Exec.prototype.CloseGame = function(args) { ...@@ -122,7 +130,7 @@ Exec.prototype.CloseGame = function(args) {
} }
//必须可以让用户可以有一个区块的竞猜时间 //必须可以让用户可以有一个区块的竞猜时间
if (this.context.height - game.height < MIN_WAIT_BLOCK) { if (this.context.height - game.height < MIN_WAIT_BLOCK) {
throwerr("close game must wait 2 block") throwerr("close game must wait "+MIN_WAIT_BLOCK+" block")
} }
for (var i = 0; i < matches.length; i++) { for (var i = 0; i < matches.length; i++) {
var match = matches[i] var match = matches[i]
...@@ -195,27 +203,22 @@ Exec.prototype.ForceCloseGame = function(args) { ...@@ -195,27 +203,22 @@ Exec.prototype.ForceCloseGame = function(args) {
} }
ExecLocal.prototype.NewGame = function(args) { ExecLocal.prototype.NewGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.Guess = function(args) { ExecLocal.prototype.Guess = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.CloseGame = function(args) { ExecLocal.prototype.CloseGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.ForceCloseGame = function(args) { ExecLocal.prototype.ForceCloseGame = function(args) {
return localprocess.call(this, args)
}
function localprocess(args) {
var local = MatchGameTable(this.kvc) var local = MatchGameTable(this.kvc)
local.addlogs(this.logs) local.addlogs(this.logs)
local.save() local.save()
...@@ -224,16 +227,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) { ...@@ -224,16 +227,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) {
Query.prototype.ListGameByAddr = function(args) { Query.prototype.ListGameByAddr = function(args) {
var local = GameLocalTable(this.kvc) var local = GameLocalTable(this.kvc)
return local.query("addr", args.addr, args.primaryKey, args.count, args.direction) var q = local.query("addr", args.addr, args.primaryKey, args.count, args.direction)
return querytojson(q)
} }
/* Query.prototype.ListMatchByAddr = function(args) {
game ->(1 : n) match var local = MatchGameTable(this.kvc)
game.gameid -> primary var q= local.query("addr#status", args["addr#status"], args.primaryKey, args.count, args.direction)
return querytojson(q)
}
match.gameid -> fk
match.id -> primary
*/
function GameLocalTable(kvc) { function GameLocalTable(kvc) {
this.config = { this.config = {
"#tablename" : "game", "#tablename" : "game",
......
...@@ -47,17 +47,22 @@ Exec.prototype.Guess = function(args) { ...@@ -47,17 +47,22 @@ Exec.prototype.Guess = function(args) {
match.id = this.txID() match.id = this.txID()
match.addr = this.context.from match.addr = this.context.from
match.hash = this.context.txhash match.hash = this.context.txhash
match.num = args.num
var game = this.kvc.get(match.gameid) var game = this.kvc.get(match.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("guess: game id not found")
} }
if (game.status != 1) { if (game.status != 1) {
throwerr("game status not open") throwerr("guess: game status not open")
}
if (this.context.from == game.addr) {
throwerr("guess: game addr and match addr is same")
} }
if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) { if (match.bet < 1 * COINS || match.bet > game.bet / RAND_MAX) {
throwerr("match bet litte than 1 or big than game.bet/10") throwerr("match bet litte than 1 or big than game.bet/10")
} }
var err = this.acc.execFrozen(this.name, this.context.from, game.bet) var err = this.acc.execFrozen(this.name, this.context.from, match.bet)
console.log(this.name, this.context.from, err)
throwerr(err) throwerr(err)
this.kvc.add(match.id, match) this.kvc.add(match.id, match)
this.kvc.addlog(match) this.kvc.addlog(match)
...@@ -65,18 +70,19 @@ Exec.prototype.Guess = function(args) { ...@@ -65,18 +70,19 @@ Exec.prototype.Guess = function(args) {
} }
Exec.prototype.CloseGame = function(args) { Exec.prototype.CloseGame = function(args) {
var local = new MatchLocalTable(this.kvc) var local = MatchLocalTable(this.kvc)
var game = this.kvc.get(args.id) var game = this.kvc.get(args.gameid)
if (!game) { if (!game) {
throwerr("game id not found") throwerr("game id not found")
} }
var matches = local.getmath(args.id) var querykey = local.get("gameid", args)
var matches = local.query("gameid", querykey, "", 0, 1)
if (!matches) { if (!matches) {
matches = [] matches = []
} }
var n = -1 var n = -1
for (var i = 0; i < RAND_MAX; i ++) { for (var i = 0; i < RAND_MAX; i++) {
if (sha256(args.randstr + i) == game.randhash) { if (Sha256(args.randstr + i) == game.randhash) {
n = i n = i
} }
} }
...@@ -85,7 +91,7 @@ Exec.prototype.CloseGame = function(args) { ...@@ -85,7 +91,7 @@ Exec.prototype.CloseGame = function(args) {
} }
//必须可以让用户可以有一个区块的竞猜时间 //必须可以让用户可以有一个区块的竞猜时间
if (this.context.height - game.height < MIN_WAIT_BLOCK) { if (this.context.height - game.height < MIN_WAIT_BLOCK) {
throwerr("close game must wait 2 block") throwerr("close game must wait "+MIN_WAIT_BLOCK+" block")
} }
for (var i = 0; i < matches.length; i++) { for (var i = 0; i < matches.length; i++) {
var match = matches[i] var match = matches[i]
...@@ -158,27 +164,22 @@ Exec.prototype.ForceCloseGame = function(args) { ...@@ -158,27 +164,22 @@ Exec.prototype.ForceCloseGame = function(args) {
} }
ExecLocal.prototype.NewGame = function(args) { ExecLocal.prototype.NewGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.Guess = function(args) { ExecLocal.prototype.Guess = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.CloseGame = function(args) { ExecLocal.prototype.CloseGame = function(args) {
var local = MatchGameTable(this.kvc) return localprocess.call(this, args)
local.addlogs(this.logs)
local.save()
return this.kvc.receipt()
} }
ExecLocal.prototype.ForceCloseGame = function(args) { ExecLocal.prototype.ForceCloseGame = function(args) {
return localprocess.call(this, args)
}
function localprocess(args) {
var local = MatchGameTable(this.kvc) var local = MatchGameTable(this.kvc)
local.addlogs(this.logs) local.addlogs(this.logs)
local.save() local.save()
...@@ -187,16 +188,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) { ...@@ -187,16 +188,16 @@ ExecLocal.prototype.ForceCloseGame = function(args) {
Query.prototype.ListGameByAddr = function(args) { Query.prototype.ListGameByAddr = function(args) {
var local = GameLocalTable(this.kvc) var local = GameLocalTable(this.kvc)
return local.query("addr", args.addr, args.primaryKey, args.count, args.direction) var q = local.query("addr", args.addr, args.primaryKey, args.count, args.direction)
return querytojson(q)
} }
/* Query.prototype.ListMatchByAddr = function(args) {
game ->(1 : n) match var local = MatchGameTable(this.kvc)
game.gameid -> primary var q= local.query("addr#status", args["addr#status"], args.primaryKey, args.count, args.direction)
return querytojson(q)
}
match.gameid -> fk
match.id -> primary
*/
function GameLocalTable(kvc) { function GameLocalTable(kvc) {
this.config = { this.config = {
"#tablename" : "game", "#tablename" : "game",
......
package executor_test package executor_test
import ( import (
"encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
"testing" "testing"
...@@ -134,12 +135,33 @@ func TestJsGame(t *testing.T) { ...@@ -134,12 +135,33 @@ func TestJsGame(t *testing.T) {
block = mocker.GetLastBlock() block = mocker.GetLastBlock()
balance = mocker.GetExecAccount(block.StateHash, "user.jsvm."+contractName, mocker.GetHotAddress()).Balance balance = mocker.GetExecAccount(block.StateHash, "user.jsvm."+contractName, mocker.GetHotAddress()).Balance
assert.Equal(t, 100*types.Coin, balance) assert.Equal(t, 100*types.Coin, balance)
reqtx = &rpctypes.CreateTx{
To: address.ExecAddress("user.jsvm." + contractName),
Amount: 100 * types.Coin,
Note: "12312",
IsWithdraw: false,
IsToken: false,
TokenSymbol: "",
ExecName: "user.jsvm." + contractName,
}
err = mocker.GetJSONC().Call("Chain33.CreateRawTransaction", reqtx, &txhex)
assert.Nil(t, err)
hash, err = mocker.SendAndSign(mocker.GetGenesisKey(), txhex)
assert.Nil(t, err)
txinfo, err = mocker.WaitTx(hash)
assert.Nil(t, err)
assert.Equal(t, txinfo.Receipt.Ty, int32(2))
block = mocker.GetLastBlock()
balance = mocker.GetExecAccount(block.StateHash, "user.jsvm."+contractName, mocker.GetGenesisAddress()).Balance
assert.Equal(t, 100*types.Coin, balance)
t.Log(mocker.GetGenesisAddress())
//2.2 调用 hello 函数(随机数,用nonce) //2.2 调用 hello 函数(随机数,用nonce)
privhash := common.Sha256(mocker.GetHotKey().Bytes()) privhash := common.Sha256(mocker.GetHotKey().Bytes())
nonce := rand.Int63() nonce := rand.Int63()
num := rand.Int63() % 10 num := rand.Int63() % 10
realhash := common.Sha256([]byte(string(privhash) + ":" + fmt.Sprint(nonce))) realhash := common.ToHex(common.Sha256([]byte(string(privhash) + ":" + fmt.Sprint(nonce))))
myhash := common.ToHex(common.Sha256([]byte(string(realhash) + fmt.Sprint(num)))) myhash := common.ToHex(common.Sha256([]byte(realhash + fmt.Sprint(num))))
call := &jsproto.Call{ call := &jsproto.Call{
Funcname: "NewGame", Funcname: "NewGame",
...@@ -153,14 +175,71 @@ func TestJsGame(t *testing.T) { ...@@ -153,14 +175,71 @@ func TestJsGame(t *testing.T) {
} }
err = mocker.GetJSONC().Call("Chain33.CreateTransaction", req, &txhex) err = mocker.GetJSONC().Call("Chain33.CreateTransaction", req, &txhex)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(mocker.GetHotAddress())
hash, err = mocker.SendAndSignNonce(mocker.GetHotKey(), txhex, nonce) hash, err = mocker.SendAndSignNonce(mocker.GetHotKey(), txhex, nonce)
assert.Nil(t, err) assert.Nil(t, err)
txinfo, err = mocker.WaitTx(hash) txinfo, err = mocker.WaitTx(hash)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, txinfo.Receipt.Ty, int32(2)) assert.Equal(t, txinfo.Receipt.Ty, int32(2))
gameid := txinfo.Height*100000 + txinfo.Index
//2.3 guess a number (win)
call = &jsproto.Call{
Funcname: "Guess",
Name: contractName,
Args: fmt.Sprintf(`{"bet": %d, "gameid" : "%d", "num" : %d}`, 1*types.Coin, gameid, num),
}
req = &rpctypes.CreateTxIn{
Execer: "user." + ptypes.JsX + "." + contractName,
ActionName: "Call",
Payload: types.MustPBToJSON(call),
}
err = mocker.GetJSONC().Call("Chain33.CreateTransaction", req, &txhex)
assert.Nil(t, err)
hash, err = mocker.SendAndSignNonce(mocker.GetGenesisKey(), txhex, nonce)
assert.Nil(t, err)
txinfo, err = mocker.WaitTx(hash)
assert.Nil(t, err)
assert.Equal(t, txinfo.Receipt.Ty, int32(2))
//3. query 函数查询 //2.4 guess a num (failed)
call = &jsproto.Call{
Funcname: "Guess",
Name: contractName,
Args: fmt.Sprintf(`{"bet": %d, "gameid" : "%d", "num" : %d}`, 1*types.Coin, gameid, num+1),
}
req = &rpctypes.CreateTxIn{
Execer: "user." + ptypes.JsX + "." + contractName,
ActionName: "Call",
Payload: types.MustPBToJSON(call),
}
err = mocker.GetJSONC().Call("Chain33.CreateTransaction", req, &txhex)
assert.Nil(t, err)
t.Log(mocker.GetHotAddress())
hash, err = mocker.SendAndSignNonce(mocker.GetGenesisKey(), txhex, nonce)
assert.Nil(t, err)
txinfo, err = mocker.WaitTx(hash)
assert.Nil(t, err)
assert.Equal(t, txinfo.Receipt.Ty, int32(2))
//2.5 close the game
call = &jsproto.Call{
Funcname: "CloseGame",
Name: contractName,
Args: fmt.Sprintf(`{"gameid":%d, "randstr":"%s"}`, gameid, realhash),
}
req = &rpctypes.CreateTxIn{
Execer: "user." + ptypes.JsX + "." + contractName,
ActionName: "Call",
Payload: types.MustPBToJSON(call),
}
err = mocker.GetJSONC().Call("Chain33.CreateTransaction", req, &txhex)
assert.Nil(t, err)
t.Log(mocker.GetHotAddress())
hash, err = mocker.SendAndSignNonce(mocker.GetHotKey(), txhex, nonce)
assert.Nil(t, err)
txinfo, err = mocker.WaitTx(hash)
assert.Nil(t, err)
assert.Equal(t, txinfo.Receipt.Ty, int32(2))
//3.1 query game 函数查询
call = &jsproto.Call{ call = &jsproto.Call{
Funcname: "ListGameByAddr", Funcname: "ListGameByAddr",
Name: contractName, Name: contractName,
...@@ -175,4 +254,35 @@ func TestJsGame(t *testing.T) { ...@@ -175,4 +254,35 @@ func TestJsGame(t *testing.T) {
err = mocker.GetJSONC().Call("Chain33.Query", query, &queryresult) err = mocker.GetJSONC().Call("Chain33.Query", query, &queryresult)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(queryresult.Data) t.Log(queryresult.Data)
//3.2 query match -> status 函数
call = &jsproto.Call{
Funcname: "JoinKey",
Name: contractName,
Args: fmt.Sprintf(`{"left":"%s", "right" : "%s"}`, mocker.GetGenesisAddress(), "2"),
}
query = &rpctypes.Query4Jrpc{
Execer: "user." + ptypes.JsX + "." + contractName,
FuncName: "Query",
Payload: types.MustPBToJSON(call),
}
err = mocker.GetJSONC().Call("Chain33.Query", query, &queryresult)
assert.Nil(t, err)
joinkey := queryresult.Data
reqjson := make(map[string]interface{})
reqjson["addr#status"] = joinkey
reqdata, _ := json.Marshal(reqjson)
call = &jsproto.Call{
Funcname: "ListMatchByAddr",
Name: contractName,
Args: string(reqdata),
}
query = &rpctypes.Query4Jrpc{
Execer: "user." + ptypes.JsX + "." + contractName,
FuncName: "Query",
Payload: types.MustPBToJSON(call),
}
err = mocker.GetJSONC().Call("Chain33.Query", query, &queryresult)
assert.Nil(t, err)
t.Log(queryresult.Data)
} }
...@@ -29,11 +29,14 @@ Table.prototype.joinkey = function(left, right) { ...@@ -29,11 +29,14 @@ Table.prototype.joinkey = function(left, right) {
} }
Table.prototype.get = function(key, row) { Table.prototype.get = function(key, row) {
if (!isstring(row)) {
row = tojson(row)
}
return table_get(this.id, key, row) return table_get(this.id, key, row)
} }
Table.prototype.query = function(indexName, prefix, primaryKey, count, direction) { function query_list(indexName, prefix, primaryKey, count, direction) {
if (!count) { if (count !== 0 && !count) {
count = 20 count = 20
} }
if (!direction) { if (!direction) {
...@@ -49,7 +52,14 @@ Table.prototype.query = function(indexName, prefix, primaryKey, count, direction ...@@ -49,7 +52,14 @@ Table.prototype.query = function(indexName, prefix, primaryKey, count, direction
indexName = "" indexName = ""
} }
var q = table_query(this.id, indexName, prefix, primaryKey, count, direction) var q = table_query(this.id, indexName, prefix, primaryKey, count, direction)
return tojson(q) if (q.err) {
return null
}
return q
}
Table.prototype.query = function(indexName, prefix, primaryKey, count, direction) {
return query_list.call(this, indexName, prefix, primaryKey, count, direction)
} }
Table.prototype.replace = function(obj) { Table.prototype.replace = function(obj) {
...@@ -106,12 +116,31 @@ function print(obj) { ...@@ -106,12 +116,31 @@ function print(obj) {
JoinTable.prototype.save = function() { JoinTable.prototype.save = function() {
var ret = table_save(this.id) var ret = table_save(this.id)
print(ret)
if (this.kvc) { if (this.kvc) {
this.kvc.save(ret) this.kvc.save(ret)
} }
return ret return ret
} }
JoinTable.prototype.get = function(key, row) {
if (!isstring(row)) {
row = tojson(row)
}
return table_get(this.id, key, row)
}
JoinTable.prototype.query = function(indexName, prefix, primaryKey, count, direction) {
return query_list.call(this, indexName, prefix, primaryKey, count, direction)
}
function querytojson(data) {
if (!data) {
return "[]"
}
return tojson(data)
}
JoinTable.prototype.close = function() { JoinTable.prototype.close = function() {
table_close(this.lefttable.id) table_close(this.lefttable.id)
table_close(this.righttable.id) table_close(this.righttable.id)
...@@ -421,6 +450,10 @@ function Query(context) { ...@@ -421,6 +450,10 @@ function Query(context) {
} }
} }
Query.prototype.JoinKey = function(args) {
return table_joinkey(args.left, args.right).value
}
function throwerr(err) { function throwerr(err) {
if (err) { if (err) {
throw new Error(err) throw new Error(err)
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"regexp" "regexp"
"strconv"
"strings" "strings"
"github.com/33cn/chain33/common/db" "github.com/33cn/chain33/common/db"
...@@ -468,28 +469,34 @@ func (row *JSONRow) SetPayload(data types.Message) error { ...@@ -468,28 +469,34 @@ func (row *JSONRow) SetPayload(data types.Message) error {
//Get value of row //Get value of row
func (row *JSONRow) Get(key string) ([]byte, error) { func (row *JSONRow) Get(key string) ([]byte, error) {
v, err := row.get(key)
return v, err
}
func (row *JSONRow) get(key string) ([]byte, error) {
if format, ok := row.config[key]; ok { if format, ok := row.config[key]; ok {
if data, ok := row.data[key]; ok { if data, ok := row.data[key]; ok {
if n, ok := data.(json.Number); ok { if row.isint.Match([]byte(format)) { //int
if row.isint.Match([]byte(format)) { //ini s := fmt.Sprint(data)
num, err := n.Int64() num, err := strconv.ParseInt(s, 10, 64)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return []byte(fmt.Sprintf(format, num)), nil return []byte(fmt.Sprintf(format, num)), nil
} else if row.isfloat.Match([]byte(format)) { } else if row.isfloat.Match([]byte(format)) { //float
num, err := n.Float64() s := fmt.Sprint(data)
if err != nil { num, err := strconv.ParseFloat(s, 64)
return nil, err if err != nil {
} return nil, err
return []byte(fmt.Sprintf(format, num)), nil }
} else { return []byte(fmt.Sprintf(format, num)), nil
s := n.String() } else { //string
return []byte(fmt.Sprintf(format, s)), nil if n, ok := data.(json.Number); ok {
data = n.String()
} }
} }
return []byte(fmt.Sprintf(format, data)), nil return []byte(fmt.Sprintf(format, data)), nil
} }
} }
return nil, types.ErrNotFound return nil, errors.New("get key " + key + "from data err")
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment