SC Arguments: [Name:SC_ACTION Type:uint64 Value:'0' Name:SC_ID Type:hash Value:'d3dae2a2dddfc9958ed371d4ea32bf21416e28bb90d2b92ddce52b120c7358d5' Name:c Type:string Value:'// DCLOB v0.90
Function Initialize(a1 String,a2 String,fee Uint64) Uint64
10 IF EXISTS("owner") THEN GOTO 200
20 STORE("owner",SIGNER())
30 STORE("a1",HEXDECODE(a1))
40 STORE("a2",HEXDECODE(a2))
50 STORE("fee",fee)
60 STORE("memloc",0)
70 STORE("hist",0)
80 STORE("o1",0)
90 STORE("o2",0)
100 STORE("buy",newNode(0,0,0))
110 STORE("sell",newNode(0,0,0))
200 RETURN 0
End Function
Function UpdateCode(c String) Uint64
10 IF LOAD("owner") != SIGNER() THEN GOTO 30
20 UPDATE_SC_CODE(c)
30 RETURN 0
End Function
Function UpdateFee(f Uint64) Uint64
10 IF LOAD("owner") != SIGNER() THEN GOTO 30
20 STORE("fee",f)
30 RETURN 0
End Function
Function Withdraw() Uint64
10 IF LOAD("owner") != SIGNER() THEN GOTO 80
20 IF LOAD("o1") == 0 THEN GOTO 50
30 SEND_ASSET_TO_ADDRESS(LOAD("owner"),LOAD("o1"),LOAD("a1"))
40 STORE("o1",0)
50 IF LOAD("o2") == 0 THEN GOTO 80
60 SEND_ASSET_TO_ADDRESS(LOAD("owner"),LOAD("o2"),LOAD("a2"))
70 STORE("o2",0)
80 RETURN 0
End Function
Function getLoc() Uint64
10 DIM m AS Uint64
20 LET m = LOAD("memloc") + 1
30 STORE("memloc",m)
40 RETURN m
End Function
Function stoHist(x Uint64,y Uint64,s1 String,s2 String)
10 DIM h AS Uint64
20 LET h = LOAD("hist")
30 STORE("h:"+h,":"+BLOCK_TIMESTAMP()+":"+x+":"+y+":"+HEX(SUBSTR(s1,0,4))+":"+HEX(SUBSTR(s2,0,4)))
40 STORE("hist",(h+1)%1000)
50 RETURN
End Function
Function newNode(p Uint64,k Uint64,d Uint64) Uint64
10 DIM n AS Uint64
20 LET n = getLoc()
30 STORE("np:"+n,p)
40 STORE("nk:"+n,k)
50 STORE("nd:"+n,d)
60 STORE("nl:"+n,0)
70 STORE("nr:"+n,0)
80 RETURN n
End Function
Function delNode(n Uint64)
10 DELETE("np:"+n)
20 DELETE("nk:"+n)
30 DELETE("nd:"+n)
40 DELETE("nl:"+n)
50 DELETE("nr:"+n)
60 RETURN
End Function
Function getExt(n Uint64,dir String) Uint64
10 DIM x AS Uint64
20 IF LOAD("nk:"+n) != 0 THEN GOTO 40
30 RETURN 0
40 LET x = LOAD(dir+n)
50 IF x == 0 THEN GOTO 80
60 LET n = x
70 GOTO 20
80 RETURN n
End Function
Function btGetFirst(n Uint64) Uint64
10 RETURN getExt(n,"nl:")
End Function
Function btGetLast(n Uint64) Uint64
10 RETURN getExt(n,"nr:")
End Function
Function btGetNext(n Uint64) Uint64
10 DIM r,p AS Uint64
20 IF n == 0 THEN GOTO 90
30 LET r = LOAD("nr:"+n)
40 IF r == 0 THEN GOTO 60
50 RETURN btGetFirst(r)
60 LET p = LOAD("np:"+n)
70 IF p == 0 THEN GOTO 90
80 IF LOAD("nl:"+p) != n THEN GOTO 100
90 RETURN p
100 LET n = p
110 GOTO 60
End Function
Function btGetPrev(n Uint64) Uint64
10 DIM l,p AS Uint64
20 IF n == 0 THEN GOTO 90
30 LET l = LOAD("nl:"+n)
40 IF l == 0 THEN GOTO 60
50 RETURN btGetLast(l)
60 LET p = LOAD("np:"+n)
70 IF p == 0 THEN GOTO 90
80 IF LOAD("nr:"+p) != n THEN GOTO 100
90 RETURN p
100 LET n = p
110 GOTO 60
End Function
Function btInsert(root Uint64,k Uint64,d Uint64) Uint64
10 DIM n,p,tk AS Uint64
20 IF k != 0 THEN GOTO 40
30 RETURN 0
40 LET n = root
45 LET tk = LOAD("nk:"+n)
50 IF tk != 0 THEN GOTO 90
60 STORE("nk:"+n,k)
70 STORE("nd:"+n,d)
80 RETURN n
90 IF n == 0 THEN GOTO 200
95 LET tk = LOAD("nk:"+n)
100 LET p = n
110 IF k >= tk THEN GOTO 140
120 LET n = LOAD("nl:"+n)
130 GOTO 90
140 LET n = LOAD("nr:"+n)
150 GOTO 90
200 LET n = newNode(p,k,d)
210 IF k >= tk THEN GOTO 240
220 STORE("nl:"+p,n)
230 RETURN n
240 STORE("nr:"+p,n)
250 RETURN n
End Function
Function btDelete(root Uint64,n Uint64) Uint64
10 DIM l,r,p,n1,cn AS Uint64
20 LET l = LOAD("nl:"+n)
30 LET r = LOAD("nr:"+n)
40 IF l == 0 || r == 0 THEN GOTO 200
50 LET n1 = btGetFirst(r)
60 LET p = LOAD("nd:"+n1)
70 STORE("nk:"+n,LOAD("nk:"+n1))
80 STORE("nd:"+n,p)
90 STORE("tn:"+p,n)
100 RETURN btDelete(root,n1)
200 LET p = LOAD("np:"+n)
205 IF r == 0 THEN GOTO 225
210 LET cn = r
220 GOTO 300
225 IF l == 0 THEN GOTO 250
230 LET cn = l
250 IF cn != 0 || p != 0 THEN GOTO 300
260 STORE("nk:"+n,0)
270 STORE("nd:"+n,"")
280 RETURN root
300 IF p == 0 THEN GOTO 400
310 IF LOAD("nl:"+p) == n THEN GOTO 340
320 STORE("nr:"+p,cn)
330 GOTO 350
340 STORE("nl:"+p,cn)
350 IF cn == 0 THEN GOTO 450
360 STORE("np:"+cn,p)
370 GOTO 450
400 LET root = cn
410 STORE("np:"+root,0)
450 delNode(n)
500 RETURN root
End Function
Function multDiv(a Uint64,b Uint64,c Uint64) Uint64
10 DIM base,maxdiv,res AS Uint64
20 LET base = 4294967296
30 LET maxdiv = (base-1)*base + (base-1)
40 LET res = (a/c)*b + (a%c)*(b/c)
50 LET a = a % c
60 LET b = b % c
70 IF (a == 0 || b == 0) THEN GOTO 1000
100 IF (c >= base) THEN GOTO 200
110 LET res = res + (a*b/c)
120 GOTO 1000
200 DIM norm,ah,al,bh,bl,ch,cl,p0,p1,p2,q0,q1,rhat AS Uint64
210 LET norm = maxdiv/c
220 LET c = c*norm
230 LET a = a*norm
300 LET ah = a / base
310 LET al = a % base
320 LET bh = b / base
330 LET bl = b % base
340 LET ch = c / base
350 LET cl = c % base
400 LET p0 = al*bl
410 LET p1 = p0 / base + al*bh
420 LET p0 = p0 % base
430 LET p2 = p1 / base + ah*bh
440 LET p1 = (p1 % base) + ah*bl
450 LET p2 = p2 + p1 / base
460 LET p1 = p1 % base
500 LET p2 = p2 % c
510 LET q1 = p2 / ch
520 LET rhat = p2 % ch
600 IF (q1 < base && (rhat >= base || q1*cl <= rhat*base+p1)) THEN GOTO 700
610 LET q1 = q1 - 1
620 LET rhat = rhat + ch
630 GOTO 600
700 LET p1 = ((p2 % base) * base + p1) - q1*cl
710 LET p2 = (p2 / base * base + p1 / base) - q1*ch
720 LET p1 = (p1 % base) + (p2 % base) * base
730 LET q0 = p1 / ch
740 LET rhat = p1 % ch
800 IF (q0 < base && (rhat >= base || q0*cl <= rhat*base+p0)) THEN GOTO 900
810 LET q0 = q0 - 1
820 LET rhat = rhat + ch
830 GOTO 800
900 LET res = res + q0 + q1*base
1000 RETURN res
End Function
Function payAsset(s String,a String,o String,f Uint64)
10 DIM x AS Uint64
20 IF MAPEXISTS(s+a) == 0 THEN GOTO 60
30 LET x = multDiv(MAPGET(s+a),f,10000)
40 SEND_ASSET_TO_ADDRESS(s,MAPGET(s+a)-x,a)
50 STORE(o,LOAD(o)+x)
60 RETURN
End Function
Function payout(a1 String,a2 String,f Uint64)
10 DIM n,i AS Uint64
20 DIM s AS String
30 IF MAPEXISTS("n") != 1 THEN GOTO 100
40 LET n = MAPGET("n")
50 LET s = MAPGET("n"+i)
60 payAsset(s,a1,"o1",f)
70 payAsset(s,a2,"o2",f)
80 LET i = i + 1
90 IF i < n THEN GOTO 50
100 RETURN
End Function
Function tran(s String,a String,v Uint64)
10 DIM t,n AS Uint64
20 IF MAPEXISTS(s+a) != 1 THEN GOTO 40
30 LET t = MAPGET(s+a)
40 MAPSTORE(s+a,t+v)
50 IF MAPEXISTS(s) THEN GOTO 110
60 MAPSTORE(s,"")
70 IF MAPEXISTS("n") != 1 THEN GOTO 90
80 LET n = MAPGET("n")
90 MAPSTORE("n"+n,s)
100 MAPSTORE("n",n+1)
110 RETURN
End Function
Function stoTx(tx Uint64,n Uint64,s String,t String,o1 Uint64,o2 Uint64,v1 Uint64,v2 Uint64)
10 STORE("tn:"+tx,n)
20 STORE("ts:"+tx,s)
30 STORE("tt:"+tx,t)
40 STORE("to1:"+tx,o1)
50 STORE("to2:"+tx,o2)
60 STORE("tv1:"+tx,v1)
70 STORE("tv2:"+tx,v2)
80 RETURN
End Function
Function delTx(tx Uint64)
10 DELETE("tn:"+tx)
20 DELETE("ts:"+tx)
30 DELETE("tt:"+tx)
40 DELETE("to1:"+tx)
50 DELETE("to2:"+tx)
60 DELETE("tv1:"+tx)
70 DELETE("tv2:"+tx)
80 RETURN
End Function
Function match(dir String,n Uint64,a1 String,a2 String,xs String,xv1 Uint64,xv2 Uint64)
10 DIM ys AS String
20 DIM tx,t1,t2,price,yv1,yv2 AS Uint64
30 LET tx = LOAD("nd:"+n)
40 LET ys = LOAD("ts:"+tx)
50 LET yv1 = LOAD("tv1:"+tx)
60 LET yv2 = LOAD("tv2:"+tx)
70 LET price = LOAD("nk:"+n)
80 LET t1 = MIN(xv1,yv1)
90 LET t2 = multDiv(t1,price,10000000)
110 MAPSTORE("v1",xv1-t1)
120 STORE("tv1:"+tx,yv1-t1)
130 IF dir == "buy" THEN GOTO 300
200 tran(xs,a1,t1)
210 tran(ys,a2,t2)
220 MAPSTORE("v2",xv2-t2)
230 stoHist(t1,price,xs,ys)
240 GOTO 400
300 tran(ys,a1,t1)
310 tran(xs,a2,t2)
320 STORE("tv2:"+tx,yv2-t2)
330 stoHist(t1,price,ys,xs)
400 IF yv1 > t1 THEN GOTO 520
410 IF yv2 <= t2 THEN GOTO 500
420 tran(ys,a2,yv2-t2)
500 STORE(dir,btDelete(LOAD(dir),n))
510 delTx(tx)
520 RETURN
End Function
Function Sell(price Uint64) Uint64
10 DIM n,n1,o1,v1,tx AS Uint64
20 DIM s,a1,a2 AS String
30 LET s = SIGNER()
40 LET a1 = LOAD("a1")
50 LET a2 = LOAD("a2")
60 LET o1 = ASSETVALUE(a1)
70 IF o1 == 0 THEN GOTO 500
80 LET v1 = o1
90 LET n = btGetLast(LOAD("buy"))
200 IF n == 0 THEN GOTO 300
210 IF LOAD("nk:"+n) < price THEN GOTO 300
220 LET n1 = btGetPrev(n)
230 match("buy",n,a1,a2,s,v1,0)
240 LET v1 = MAPGET("v1")
260 LET n = n1
270 IF v1 != 0 THEN GOTO 200 ELSE GOTO 400
300 LET tx = getLoc()
310 LET n = btInsert(LOAD("sell"),price,tx)
320 stoTx(tx,n,s,"sell",o1,0,v1,0)
400 payout(a1,a2,LOAD("fee"))
410 RETURN 0
500 RETURN 1
End Function
Function Buy(o1 Uint64,price Uint64) Uint64
10 DIM n,n1,o2,v1,v2,tx AS Uint64
20 DIM s,a1,a2 AS String
30 LET s = SIGNER()
40 LET a1 = LOAD("a1")
50 LET a2 = LOAD("a2")
60 LET o2 = ASSETVALUE(a2)
70 IF o2 < multDiv(o1,price,10000000) THEN GOTO 500
80 LET v1 = o1
90 LET v2 = o2
100 LET n = btGetFirst(LOAD("sell"))
200 IF n == 0 THEN GOTO 300
210 IF LOAD("nk:"+n) > price THEN GOTO 300
220 LET n1 = btGetNext(n)
230 match("sell",n,a1,a2,s,v1,v2)
240 LET v1 = MAPGET("v1")
250 LET v2 = MAPGET("v2")
260 LET n = n1
270 IF v1 != 0 THEN GOTO 200
280 IF v2 == 0 THEN GOTO 400
290 tran(s,a2,v2)
295 GOTO 400
300 LET tx = getLoc()
310 LET n = btInsert(LOAD("buy"),price,tx)
320 stoTx(tx,n,s,"buy",o1,o2,v1,v2)
400 payout(a1,a2,LOAD("fee"))
410 RETURN 0
500 RETURN 1
End Function
Function Cancel(tx Uint64) Uint64
10 DIM s,t AS String
20 IF EXISTS("ts:"+tx) == 0 THEN GOTO 500
30 LET s = LOAD("ts:"+tx)
40 LET t = LOAD("tt:"+tx)
50 IF SIGNER() != s && SIGNER() != LOAD("owner") THEN GOTO 500
60 IF t == "buy" THEN GOTO 200
100 tran(s,LOAD("a1"),LOAD("tv1:"+tx))
110 GOTO 300
200 tran(s,LOAD("a2"),LOAD("tv2:"+tx))
300 payout(LOAD("a1"),LOAD("a2"),0)
310 STORE(t,btDelete(LOAD(t),LOAD("tn:"+tx)))
320 delTx(tx)
400 RETURN 0
500 RETURN 1
End Function
' Name:entrypoint Type:string Value:'UpdateCode'] |